文件我有一個CSV帶時間戳和一些數據值文件:在CSV更換色譜柱用一分鐘的間隔時間戳記
1455840000,76.357,899.500,326.717,8.000
1455840060,76.490,899.650,326.150,8.000
...etc
但我想更換新的時間戳值的時間戳列。最後一行應該是當前時間,並且所有先前的行應比它之後的行早一分鐘。
如何使用shell腳本執行此操作慶典/ AWK?
文件我有一個CSV帶時間戳和一些數據值文件:在CSV更換色譜柱用一分鐘的間隔時間戳記
1455840000,76.357,899.500,326.717,8.000
1455840060,76.490,899.650,326.150,8.000
...etc
但我想更換新的時間戳值的時間戳列。最後一行應該是當前時間,並且所有先前的行應比它之後的行早一分鐘。
如何使用shell腳本執行此操作慶典/ AWK?
則可以反向使用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
根據我對Aaron的回答的評論,在Q中沒有跡象表明OP正在運行可能包含'tac'的操作系統,所以我提到了一些替代方案。 – ghoti
這裏是我會怎麼做:
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
如果您使用的操作系統不包含'tac'(如FreeBSD或OS X或Solaris或AIX等),請檢查您的'tail'命令是否有'-r'選項。如果失敗了,你可以用'awk'{L [i ++] = $ 0}得到類似的結果(假設你有內存來保存文件)END {for(j = i-1; j> = 0;)print L [J - ]}「'。 – ghoti
這羚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}
'strftime()'函數是GNU awk的一部分,但不是我知道的其他變體。 – ghoti
這可能是你想要什麼:
$ 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
我們如何知道'start'和'結束'時間戳?我們從哪裏開始和結束? – Inian
@Inian結束時間戳是當前時間。然後以相反的順序在一分鐘內遞減到文件的開始遞減。該文件可以是任何長度,因此除了計算行數之外,我們不知道開始時間戳。 – mtmacdonald
當你說_然後以相反的順序迭代到file_的開始時,什麼定義_start_? – Inian