在背面参考上使用评估日期命令进行Sed打印

时间:2011-05-31 16:46:53

标签: bash unix date sed

我有一个文件(经常这样做),其中* nix时间的日期为Epoch的秒数,后面是我想要选择的消息和最终“线程”字段。全部用'|'分隔从sqlite DB导出...

e.g

1306003700|SENT|21
1277237887|SENT|119
1274345263|SENT|115
1261168663|RECV|21
1306832459|SENT|80
1306835346|RECV|80

基本上,我可以轻松地使用sed来选择和打印与“thread”字段匹配的行,并使用消息打印相应的时间,因此:

> cat file | sed -n "s/^\([0-9]*\)\|\(.*\)\|80$/\1 : \2/p"
1306832459 : SENT
1306835346 : RECV

但我真正想做的还是通过unix date命令传递时间字段,所以:

> cat file | sed -n "s/^\([0-9]*\)\|\(.*\)\|80$/`date -r \1` : \2/p"

但这似乎不起作用 - 尽管它似乎接受了它。它只打印出相同的(Epoch开始)日期:

Thu  1 Jan 1970 01:00:01 BST : SENT
Thu  1 Jan 1970 01:00:01 BST : RECV

如何/可以评估/插入日期命令的后向引用\ 1?

也许sed不是匹配这些行的方法(并且一次格式化输出)...

7 个答案:

答案 0 :(得分:4)

awk非常适合这个。

awk -F"|" '$3 == '80' { print system("date -r " $1), ":", $2 }' myfile.txt

应该工作。(不能保证系统调用是正确的,但没有测试它)

答案 1 :(得分:3)

这个纯粹的bash

wanted=80
(IFS=\|; while read sec message thread
do
        [[ $thread == $wanted ]] && echo $(date -r $sec) : $message
done) < datafile.txt

打印

Tue May 31 11:00:59 CEST 2011 : SENT
Tue May 31 11:49:06 CEST 2011 : RECV

您可以在“”中引用变量以获得更好的安全性......

答案 2 :(得分:1)

Perl在这里很方便:

perl -MPOSIX -F'\|' -lane '
    next unless $F[2] == "80";
    print(strftime("%Y-%m-%d %T", localtime $F[0]), " : ", $F[1])
' input.file

答案 3 :(得分:1)

这可能对您有用:

 sed -n 's/^\([0-9]*\)|\(.*\)|80$/echo "$(date -d @\1) : \2"/p' file | sh

或者你有GNU sed:

 sed -n 's/^\([0-9]*\)|\(.*\)|80$/echo "$(date -d @\1) : \2"/ep' file

答案 4 :(得分:0)

使用 awk

$(awk -F'|' '/80$/{printf("echo $(date -d @%s) : %s;",$1,$2);}' /path/to/file)

答案 5 :(得分:0)

date命令将在sed命令之前执行。

为这项工作打破perl或python可能最简单,否则你可以使用某种bash循环。

答案 6 :(得分:0)

受到Rafe上述答案的启发:

awk -F"|" '$3 == '80' { system("date -d @" $1 " | tr -d \"\n\""); print " :", $2 }' myfile.txt

对于我的日期版本,似乎-d是参数,而不是-r,并且它需要一个前导@。这里的另一个变化是执行system调用(因此日期实际上是打印,换行和全部 - 因此tr)并返回退出代码。我们并不十分关心打印退出代码(0),因此我们会在system awk之外移动print来电。