我有一个文件(经常这样做),其中* 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不是匹配这些行的方法(并且一次格式化输出)...
答案 0 :(得分:4)
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
来电。