使用日志文件中的awk将日期转换为unix时期

时间:2017-02-24 19:45:18

标签: bash awk command-line

我的文件包含格式为“[dd.mm.yyyy。] text value”的多行。我需要将其转换为“Unix epoch | text value”。我尝试使用awk来做到这一点,但我似乎无法找到正确的命令 例如,如果文件是:

[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

是否有(最好是简单的)方法来实现这一目标?我应该使用其他工具吗?

2 个答案:

答案 0 :(得分: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  

答案 1 :(得分:2)

我建议将其简化为

ProtocolVersion proto = cluster.getConfiguration().getProtocolOptions().getProtocolVersion();

String deserialize = TypeCodec.varchar().deserialize(row.getBytes(i), proto);

或者,如果您希望继续使用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