awk 打印文件中每一行和下一行的字段

标签 awk sed ksh

我有一个文件,其中包含每条消息的开始和结束时间:

msgid=1 11:34:12.410 11:34:12.464
msgid=2 11:34:12.465 11:34:12.563
msgid=3 11:34:12.563 11:34:12.577
msgid=4 11:34:12.849 11:34:12.850
msgid=5 11:34:12.950 11:34:12.951

我需要处理从一条消息结束到下一条消息开始所耗时。

这是我能想到的最好的方法,可以在一行上获取所有信息(我可以从那里获取),但是必须有一种使用 awk 和/或 sed 的更有效的方法,而不是使用 while 循环。文件中有 20K 行,因此速度相当慢。

var=`cat <file>| wc -l`
i=1
while [[ "$i" -le "$var" ]]; do
  awk 'NR=="'$i'" {print $1, $3}' <file>
  awk 'NR=="'$(($i + 1))'" {print $1, $2}' <file>
  i=$(($i + 1));
done

我用 awk 尝试过的方法总是提前记录并最终跳过一个,所以我会得到:

msgid=1 11:34:12.464 msgid=2 11:34:12.465
msgid=3 11:34:12.577 msgid=4 11:34:12.849
msgid=5 11:34:12.950 <..>

请注意,它缺少比较 msgid 2 和 3 等。

有什么想法吗?

更新我希望看到的输出格式:

msgid=1 11:34:12.464 msgid=2 11:34:12.465
msgid=2 11:34:12.563 msgid=3 11:34:12.563
msgid=3 11:34:12.577 msgid=4 11:34:12.849
msgid=4 11:34:12.850 msgid=5 11:34:12.950

谢谢, 安迪

最佳答案

每当您编写 shell 循环只是为了操作文本时,您的方法都是错误的。另外,永远不要让 shell 变量在 awk 脚本中扩展,就像您当前通过将 awk 脚本括在双引号中所做的那样。请参阅http://cfajohnson.com/shell/cus-faq-2.html#Q24 .

您显示了您不希望的输出,但不是您想要的,所以这有点猜测:

$ cat tst.awk
end { print $1, ms($2) - end }
{ end = ms($3) }
function ms(t,   a) {
    split(t,a,/[:.]/)
    return (a[1]*60*60 + a[2]*60 + a[3]) * 1000 + a[4]
}

$ awk -f tst.awk file
msgid=2 1
msgid=3 0
msgid=4 272
msgid=5 100

您也没有说明时间是否可以延续到第二天,或者 DST 是否是一个因素等,如果是这样,鉴于输入文件中缺少日期,如何处理该问题。

关于awk 打印文件中每一行和下一行的字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27451807/

相关文章:

awk - 如何提取两个单词之间的(第一次匹配)文本

linux - 在版本名称和版本号之间进行过滤

regex - 重复正则表达式替换为 SED

linux - 需要验证变量的长度并在 unix 中执行相应的操作

shell - 我可以在 unix 脚本中调用 ssh 中的函数吗

sql - Unix shell 脚本并行运行 SQL 脚本

linux - 在unix awk中将utc时间戳转换为est

linux - 需要 bash 脚本来剥离二进制文件中的版本并与数据库版本进行比较

linux - 如何从外部源向 awk 提供值?

python - bash脚本替换html中的空格