awk:防止结果被解释为shell命令

时间:2015-03-18 15:02:54

标签: date awk

我有一些日期,如下所示

2012-11-23T09:26:20 2012-11-23T09:26:48 
2012-11-23T09:26:48 2012-11-23T09:26:48 
2012-11-23T09:26:26 2012-11-23T10:49:38 
2012-11-23T10:49:38 2012-11-23T10:49:38 
2012-11-23T09:26:30 2012-11-23T12:17:13 
2012-11-23T12:17:13 2012-11-23T12:17:13 
2012-11-23T09:26:33 2012-11-23T13:39:52 
2012-11-23T13:39:52 2012-11-23T13:39:52

我想找到每一行的两个日期之间的差异。到目前为止我已经

awk '{cmd="$(( ( $(date -ud \""$2"\" +\"%s\") - $(date -ud \""$1"\" +\"%s\") ) ))"; cmd | getline diff; print diff }' < submit_start.txt

产生

sh: 28: command not found

sh: 0: command not found

sh: 4992: command not found

sh: 0: command not found

sh: 10243: command not found

sh: 0: command not found

sh: 15199: command not found

sh: 0: command not found

我似乎将结果解释为shell命令并打印“差异”。只是 似乎添加了换行符。我做错了什么?

2 个答案:

答案 0 :(得分:3)

您在命令中遗漏了echo

awk '{cmd="echo $(( ( $(date -ud \""$2"\" +\"%s\") - $(date -ud \""$1"\" +\"%s\") ) ))"; cmd | getline diff; print diff }' file

如果没有echo,您将尝试将每个结果作为命令执行。我也从行中删除了<,因为它没有必要。

正如Ed在评论中提到的那样,使用getline时需要注意一些事项。您应该测试它是否已成功,并在您完成后关闭cmd

awk '{cmd="echo $(( ( $(date -ud \""$2"\" +\"%s\") - $(date -ud \""$1"\" +\"%s\") ) ))"; diff = ( (cmd | getline line) > 0 ? line : -1 ); close(cmd); print diff }' file

或者,使用shell执行此任务没有任何害处,因为几乎所有工作都是在awk之外完成的:

while read -r dt1 dt2; do
    echo "$(( $(date -ud "$dt2" +%s) - $(date -ud "$dt1" +%s) ))"
done < file

答案 1 :(得分:1)

将GNU awk用于时间函数:

$ gawk '{print secs($2) - secs($1)} function secs(t){gsub(/[^0-9]/," ",t); return mktime(t)}' file   
28
0
4992
0
10243
0
15199
0