2012-12-26 60 views
2

我有一個日誌文件,並在它的每一行是這樣的:轉換時間戳日期時間與sed的

timestamp=1356431101, entity=xxx, event: xxxxxx 

現在我想用sed來代替時間戳問心無愧人類可讀的日期時間:

timestamp=2012-12-24 10:00:00, entity=xxx, event:xxxxx 

我的命令是:

sed "s/^timestamp=\([0-9]\{10\}\),/timestamp=\`date +%D [email protected]\1\`,/" 

但問題是,\1不能由10位數字timesta被取代相反,它總是被視爲數字1。誰能告訴我如何解決這個問題?先謝謝你!

+0

我會用'perl' :) – squiguy

+1

'sed'不支持反引號。 shell在參數列表中用'1'調用日期,並將結果傳遞給'sed'。使用不同的工具。 (或者認識到,紀元時間戳*是人類可讀的!) –

+0

由於'1356431101 = 2012-12-25 10:25:01 +00:00',這是很不清楚,有任何時區,你可以得到您在示例中指定的轉換(您通常不能指定偏移量不是60秒倍數的時區)。正如其他人所說,「sed」不是這項任務的正確工具。我會使用Perl,但是您可以使用Python或Ruby或任何現代腳本語言;其中任何一種都比'sed'更適合這個任務(我喜歡'sed',但我認識到它的侷限性)。 –

回答

2

AWK爲這些東西更好,如果可以接受的:

awk -F, '{x=$1;sub(/.*=/,"",$1);sub(/=.*/,strftime("=%Y-%m-%d %H:%M:%S",$1),x);$1=x;}1' OFS=, file 

樣品結果:

$ cat file 
timestamp=1356431101, entity=xxx, event: xxxxxx 
timestamp=1354770380, entity=xxx, event: xxxxxx 

在運行下面的命令:

$ awk -F, '{x=$1;sub(/.*=/,"",$1);sub(/=.*/,strftime("=%Y-%m-%d %H:%M:%S",$1),x);$1=x;}1' OFS=, file 
timestamp=2012-12-25 15:55:01, entity=xxx, event: xxxxxx 
timestamp=2012-12-06 10:36:20, entity=xxx, event: xxxxxx 

第一sub命令提取時間戳。第二個使用strftime將時間戳替換爲日期和時間。 1用於打印每一行。

1

時間戳處理最好用更現代的編程語言來完成,比如Perl或Ruby。

awk '{ sub(/[0-9]{10}/, strftime("%Y-%m-%d %H:%M:%S", substr($0,11,10))) }1' file 

結果::不過,如果你有GNU AWK,你可以使用strftime()功能做到這一點

timestamp=2012-12-25 20:25:01, entity=xxx, event: xxxxxx 

您也可以閱讀更多有關GNU awk的時間函數的位置:

http://www.gnu.org/software/gawk/manual/html_node/Time-Functions.html

1

我其實更喜歡awk的方法,但爲了完整性一個perl的解決方案是這樣的:

perl -Mposix -pe 's/([0-9]{10})/POSIX::strftime("%Y-%m-%d %H:%M:%S", gmtime($1))/eg' 

如果你想匹配的領先的「時間戳=」限制的替代(雖然給出樣本輸入這似乎沒有必要),你可以使用:'s/(?:timestamp=)([0-9]*)/...

2

嘗試

cat test.txt | sed 's/^/echo "/; s/\([0-9]\{10\}\)/`date -d @\1`/; s/$/"/' | bash