2016-09-20 176 views
0

我使用一個外殼腳本來處理在下面的格式數據csv文件日期:外殼腳本解析

YYYY-MM-DD,值

每一行都有一個不同的日期和一個不同值。

我想每一行解析爲以下新的格式:

YYYY,WEEKNUM,YYYY-MM-DD,價值

,其中yyyy是4位數的年份之日起上線,weeknum是該日,月和年的星期編號。

我已經制定了使用日期命令獲取WEEKNUM,在那裏我硬編碼的日期到2016年2月1日爲例:

echo $(date -j -f '%Y-%m-%d' '2016-02-01' '+%V') 

但我只是不知道如何將此日期命令合併到sed之類的地方,我可以根據文件中該行的實際日期值動態地將yyyy和weeknum值插入到每行中。

有關如何進行的任何建議將不勝感激!

沙龍

+1

你能提供一些樣本輸入,與你的目標的預期產出一起,這樣我們就可以運行測試,並且相信他們是你正在尋找的結果? – ghoti

回答

2

這可能會做:

$ uname -sr 
Darwin 15.4.0 
$ cat inp 
2016-01-01, 5 
2016-01-09, 15 
2016-02-01, 3.14 
$ while IFS=", " read d v; do date -j -f '%Y-%m-%d' "$d" "+%Y, %V, %F, $v"; done < inp 
2016, 53, 2016-01-01, 5 
2016, 01, 2016-01-09, 15 
2016, 05, 2016-02-01, 3.14 

這一切持久性有機污染物進入了date命令的格式,避免了子shell或臨時變量的需要。

請注意選擇引號。雖然格式字符串通常被認爲是靜態的,並且通常放置在單引號中,但如果我們想要在格式中包含變量$v,則必須使用雙引號,以允許進行變量擴展。請注意,如果由於某種原因,CSV中的輸入數據「髒」,則可能會輕鬆中斷處理,因爲除了date解析第一個字段的能力之外,它不提供輸入檢查。


UPDATE

如果你要使用MacportsBrew,,那麼你的系統上安裝GNU AWK(GAWK)以下可能會表現得更好:

gawk 'BEGIN{OFS=FS=", "} {split($1,a,"-"); print a[1],strftime("%V",mktime(gensub(/-/," ","g",$1) " 00 00 00")),$1,$2}' inp 

我把它寫成一行代碼,但是爲了更容易解釋,我會打破這一點。

  • BEGIN { OFS=FS=", " } - 在腳本的開頭,定義了一個字段分隔符。
  • { - 此awk腳本的主要部分沒有「條件」,因此將針對每一行輸入執行。
  • split($1,a,"-") - 將第一個字段拆分爲數組a[],用連字符分隔。
  • print a[1], - 打印輸出,從全年
  • strftime("%V", - 後跟年周的最時間格式,
  • mktime(gensub(/-/," ","g",$1) " 00 00 00")) - 從mktime的「datespec」格式解析的時候產生的,
  • ,$1,$2} - 之後是其他兩個字段。

我還沒有開發的任何性能指標,但我敢肯定的自包含gawk的選項將運行比對輸入的每一行產生一個date命令基於bash的選項顯著更快。

+0

沒有'-r'的情況下讀取會破壞反斜槓... –

+0

@ l'L'-OP描述的輸入數據中沒有反斜槓。 – ghoti

+0

@ l'L'I - 文件中的數據非常乾淨。我不必擔心任何異常處理。 – SharonG