2017-02-24 56 views
2

我的文件包含格式爲「[dd.mm.yyyy。]文本值」的多行。我需要將其轉換爲「Unix時代|文本值」。我試圖用awk來做到這一點,但我似乎無法找到正確的命令 例如,如果該文件是:在日誌文件中使用awk將日期轉換爲unix時期

[30.08.2013 13:54:49.126] Foo 
[30.08.2013 13:56:49.126] Bar 
[30.08.2013 13:59:49.126] Foo bar 

我用下面的(可能是太複雜awk命令):

cat sample.txt | cut -c 2- |awk -F'[. :]' ' { $cmd="date --date " "\""$3$2$1" "$4":"$5":"$6"\""" +%s" ; $cmd |& getline epoch; close($cmd); printf epoch"|"; print $0 ;}';

問題是,我在正確的時間獲取時間,但是我無法訪問該行的其餘部分。 $ 0(和其他$變量)包含date命令。所以輸出

1377863689|date --date "20130830 13:54:49" +%s 
1377863809|date --date "20130830 13:56:49" +%s 
1377863989|date --date "20130830 13:59:49" +%s 

我希望得到的是

1377863689|Foo 
1377863809|Bar 
1377863989|Foo bar 

有沒有實現這一點的(最好是簡單)的方式?我應該使用其他工具嗎?

+1

什麼平臺和版本的awk? – dawg

+0

[Datetime to epoch conversion]可能重複(http://stackoverflow.com/questions/42055212/datetime-to-epoch-conversion) – dawg

回答

3

假設你有gawk(合理的假設,因爲你正在使用GNU日期),你可以做這全部內部爲gawk

$ awk 'match($0, /\[(.*)\] (.*)/, a) && 
     match(a[1], /([0-9]{2})\.([0-9]{2})\.([0-9]{4}) ([0-9:]+)(\.[0-9]+)/,b) { 
      gsub(/:/," ",b[4]) 
      s=b[3] " " b[2] " " b[1] " " b[4] 
      print mktime(s) "|" a[2] 
}' file 
1377896089|Foo 
1377896209|Bar 
1377896389|Foo bar 

或者Bash解決方案:

while IFS= read -r line; do 
    if [[ "$line" =~ \[([[:digit:]]{2})\.([[:digit:]]{2})\.([[:digit:]]{4})\ +([[:digit:]:]+)\.([[:digit:]]+)\]\ +(.*) ]] 
    then 
     printf "%s|%s\n" $(gdate +"%s" --date="${BASH_REMATCH[3]}${BASH_REMATCH[2]}${BASH_REMATCH[1]} ${BASH_REMATCH[4]}") "${BASH_REMATCH[6]}" 
    fi 
done <file 
+0

對不起,編輯錯誤;) –

+0

是的,我正在使用gawk。這解決了我的問題。謝謝。 – CyberMuz

2

我建議把它簡化爲

IFS=' |.|['; 
while read -r _ day month year hour _ name; do 
    date=$(date --date "$year$month$day $hour" +%s); 
    echo "$date|$name"; 
done < sample.txt 

或者,如果你願意繼續與awk

awk -F'[\\[\\]. ]' '{ 
    split($0,a,"] ") 
    ("date --date \"" $4$3$2" "$5"\" +%s") |& getline date 
    printf "%s|%s\n",date,a[2] 
}' sample.txt