2016-10-03 16 views
0

文件我有一個CSV帶時間戳和一些數據值文件:在CSV更換色譜柱用一分鐘的間隔時間戳記

1455840000,76.357,899.500,326.717,8.000 
1455840060,76.490,899.650,326.150,8.000 
...etc 

但我想更換新的時間戳值的時間戳列。最後一行應該是當前時間,並且所有先前的行應比它之後的行早一分鐘。

如何使用shell腳本執行此操作慶典/ AWK?

+0

我們如何知道'start'和'結束'時間戳?我們從哪裏開始和結束? – Inian

+0

@Inian結束時間戳是當前時間。然後以相反的順序在一分鐘內遞減到文件的開始遞減。該文件可以是任何長度,因此除了計算行數之外,我們不知道開始時間戳。 – mtmacdonald

+0

當你說_然後以相反的順序迭代到file_的開始時,什麼定義_start_? – Inian

回答

1

則可以反向使用tac文件內容,做了手術,然後反向回原來的順序:

tac file.txt | \ 
    awk 'BEGIN{FS=OFS=","} NR==1{"date +%s"|getline cur; $1=cur; print; next}; \ 
       {$1=cur-(60*(NR-1)); print}' | tac 
  • 對於(反轉)第一行,我們得到當前時間戳的時代,並將其保存在一個變量cur

  • 對於下一行,我們通過60 * (line number - 1)秒減去每行獲得所需的時間

請注意,時間計算可能並不像您想象的那樣精確。

例子:

% cat ts.txt 
1455840000,76.357,899.500,326.717,8.000 
1455840060,76.490,899.650,326.150,8.000 
1455840000,76.357,899.500,326.717,8.000 
1455840060,76.490,899.650,326.150,8.000 

% tac ts.txt | awk 'BEGIN{FS=OFS=","} NR==1{"date +%s"|getline cur; $1=cur; print; next}; {$1=cur-(60*(NR-1)); print}' | tac 
1475497096,76.357,899.500,326.717,8.000 
1475497156,76.490,899.650,326.150,8.000 
1475497216,76.357,899.500,326.717,8.000 
1475497276,76.490,899.650,326.150,8.000 
+0

根據我對Aaron的回答的評論,在Q中沒有跡象表明OP正在運行可能包含'tac'的操作系統,所以我提到了一些替代方案。 – ghoti

0

這裏是我會怎麼做:

tac inputFile | awk -v ts="$(date +%s)" -v OFS=, -F, '{ $4 = strftime("%c", ts - NR * 60) ; print $0 }' | tac 

tac反向輸入文件,這樣我們就可以從已知的唯一值計算的日期,目前日期。我們將在處理完每一行後恢復它。

awk-v標誌爲我們提供了使用一個變量的能力,所以我們讓bash計算當前時間戳,並將它傳遞給awk作爲UNIX時間戳(秒數自01/01/1970)。

awk-F標誌指定列分隔符。

然後在每一行中,最後一列由給定的時間戳替換,每個先前讀取的行減去60秒,我們使用strftime以人類可讀的格式顯示。

實施例:

$ cat inputFile 
a,b,c,d 
a1,b1,c1,d1 
a2,b2,c2,d2 

$ tac inputFile | awk -v ts="$(date +%s)" -v OFS=, -F, '{ $4 = strftime("%c", ts - NR * 60) ; print $0 }' | tac 
a,b,c,lun. 3 oct. 2016 15:32:29 
a1,b1,c1,lun. 3 oct. 2016 15:33:29 
a2,b2,c2,lun. 3 oct. 2016 15:34:29 
+0

如果您使用的操作系統不包含'tac'(如FreeBSD或OS X或Solaris或AIX等),請檢查您的'tail'命令是否有'-r'選項。如果失敗了,你可以用'awk'{L [i ++] = $ 0}得到類似的結果(假設你有內存來保存文件)END {for(j = i-1; j> = 0;)print L [J - ]}「'。 – ghoti

0

這羚awk腳本首先獲取當前時間戳(信號出現時間),在第一次迭代記錄着文件的NR並在第二次迭代更新的時間戳之後:

$ awk -F, 'BEGIN{ts=strftime("%s")} NR==FNR{nr=NR; next}{$1=ts-(nr-FNR)*60} 1' file file 
1455840000 76.357 899.500 326.717 8.000 
1455840060 76.490 899.650 326.150 8.000 

For compatibility with all awks — including Gnu awk — replace BEGIN{} block above with

BEGIN{"date +'%s'"|getline ts}

+1

'strftime()'函數是GNU awk的一部分,但不是我知道的其他變體。 – ghoti

1

這可能是你想要什麼:

$ cat file 
1455840000,76.357,899.500,326.717,8.000 
1455840060,76.490,899.650,326.150,8.000 
1455840000,76.357,899.500,326.717,8.000 
1455840060,76.490,899.650,326.150,8.000 
1455840000,76.357,899.500,326.717,8.000 
1455840060,76.490,899.650,326.150,8.000 

隨着GNU AWK:

$ awk 'BEGIN{FS=OFS=","; now=systime()} NR>FNR{$1 = now - (NR-2*FNR)*60; print}' file file 
1475504973,76.357,899.500,326.717,8.000 
1475505033,76.490,899.650,326.150,8.000 
1475505093,76.357,899.500,326.717,8.000 
1475505153,76.490,899.650,326.150,8.000 
1475505213,76.357,899.500,326.717,8.000 
1475505273,76.490,899.650,326.150,8.000 

與其他awks:

$ awk -v now=$(date +'%s') 'BEGIN{FS=OFS=","} NR>FNR{$1 = now - (NR-2*FNR)*60; print}' file file 
1475504973,76.357,899.500,326.717,8.000 
1475505033,76.490,899.650,326.150,8.000 
1475505093,76.357,899.500,326.717,8.000 
1475505153,76.490,899.650,326.150,8.000 
1475505213,76.357,899.500,326.717,8.000 
1475505273,76.490,899.650,326.150,8.000 
相關問題