2016-08-01 96 views
1

引用this unix.com thread上發佈的解決方案獲取當月的第N個工作日,我嘗試使用下面的代碼獲取該月的第16個工作日,但它不起作用。unix shell腳本獲得第n個工作日

currCal=`/usr/bin/cal` 
BUSINESS_DAYS=`echo $($currCal|nawk 'NR>2 {print substr($0,4,14)}' |tr "\n" " ")` 

錯誤時執行是這樣的:

NAWK:在源極線1上下文語法錯誤是 NR> 2 {打印>>> SUBSTR(測試< < < SH,4, 14)} NAWK:非法語句在源線1

我猜測它需要$0爲腳本的名稱,導致語法錯誤。請幫忙。

+0

如圖所示,命令在_single_引號中有''NR> 2 {print substr($ 0,4,14)}''。如圖所示,錯誤消息表示運行了_different_命令,其中一個參數nawk在_double_引號中,而不是_single_引號。 – John1024

+0

@ John1024謝謝約翰。我試過這個BUSINESS_DAYS ='$($ currCal | nawk「NR> 2 {print substr($ 0,4,14)}」| tr「\ n」「」)'但是同樣的錯誤。 – Pat

+0

同樣,當你需要使用單引號時,你在awk參數周圍使用了雙引號。 – John1024

回答

2

似乎有幾個問題與你有什麼以上。

首先,我爲了得到NAWK錯誤您先前已@ John1024同意這一點,你必須實際運行:

BUSINESS_DAYS=`echo $($currCal|nawk "NR>2 {print substr($0,4,14)}" |tr "\n" " ")` 

與各地NAWK腳本雙引號。

此外,一旦你解決nawk錯誤,你會遇到問題,你如何使用currCal。您將cal命令的實際輸出轉換爲currCal變量,但之後將變量值(即cal的輸出)用作|之前的命令,而不是echo將其轉換爲管道或類似物。

這引發了一個額外的問題,你爲什麼要在另一個子shell(外部`s)中使用子shell命令($()部分)的結果使用echo

最後,上面顯示的兩行只會將本月的工作日列表變爲BUSINESS_DAYS變量。他們不輸出/保存這樣的第16天。

考慮上述所有的考慮(也改變一貫使用$()子shell語法),你可能需要以下調用之一:

如果你真的需要緩存當前月份的日曆,並希望拉多天:

currCal="$(/usr/bin/cal)" 
BUSINESS_DAYS="$(echo "${currCal}" | \ 
        nawk 'NR>2 {print substr($0,4,14)}' | \ 
        tr "\n" " ")" 

DAY=16 
DAYTH_DAY="$(echo "${BUSINESS_DAYS}" | nawk -v "day=${DAY}" '{ print $day }') 

如果這只是一和完成:

DAY=16 
DAYTH_DAY="$(/usr/bin/cal | \ 
       nawk 'NR>2 {print substr($0,4,14)}' | \ 
       tr "\n" " " | \ 
       nawk -v "day=${DAY}" '{ print $day }')" 

還有一點需要注意:如果完全在awk(/ nawk)中完成,這裏的處理可以簡化,但是我想堅持已經選擇的基本框架。每在註釋請求


更新:

純POSIX awk的版本:

DAY=16 
DAYTH="$(cal | awk -v "day=${DAY}" ' 
      (NR < 3) { next ; } 
      /^.[0-9 ]/ { $1="" ; } 
      /^/|| (NF == 7) { $NF="" ; } 
      { hold=hold $0 ; } 
      END { split(hold,arr," ") ; print arr[day] ; }')" 

是,簡化是見仁見智,我敢肯定,有人可以使這個更簡潔。這是如何工作的說明:

跳過CAL輸出頭:

(NR < 3) { next ; } 

對於對週日的日期周,修剪那個星期天的日期:

/^.[0-9 ]/ { $1="" ; } 

對於在星期日(一個月的第一個星期)後開始的星期星期有整整七天,修剪當週星期六的日期:

/^/|| (NF == 7) { $NF="" ; } 

一旦線路只有工作日的日期,咖喱他們進入hold

{ hold=hold $0 ; } 

最後,劈在空間hold所以我們可以抓住第N天:

END { split(hold,arr," ") ; print arr[day] ; }')" 
+0

@ j-cordasco感謝您的詳細解釋。我在尋找邏輯來尋找工作日的邏輯,我發現了這個邏輯,在我的問題中說。在那裏,我發現邏輯與nawk,所以使用,沒有其他特殊原因。正如約翰和你所說,我可以改變我的代碼awk。不過,我需要你的幫助再次將其轉換爲「awk」。你可以幫我嗎? – Pat

0

awk,只是軟件工具

set -- $(cal -h | rev | cut --complement -b-5,20- | rev | tail -n +3) ; \ 
shift 15 ; echo $1 

輸出:

22 

cal輸出是棘手的,因爲解析:

  1. 這是右對齊。
  2. 空間分隔。
  3. 一個或兩個數字日期意味着兩個或一個分隔空格。
  4. 更多的領先空間在本月的第幾天。
  5. 沒有-h選項,解析將無法正常工作(關閉「今天」突出顯示)。