【问题标题】:awk print fields from every line in file and the following lineawk 打印文件中每一行和下一行的字段
【发布时间】:2015-02-11 15:30:24
【问题描述】:

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

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

谢谢, 安迪

【问题讨论】:

  • 考虑编辑您的问题,以从您明智地包含在问题中的示例数据中包含所需的输出。在您的第一个问题中为示例数据、代码和良好的格式 +1!继续发布(但需要输出;-)!

标签: awk sed ksh


【解决方案1】:

任何时候你写一个 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 还很陌生。那天从来没有环绕,所以我不担心。我可以处理这个。感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 2013-08-23
  • 2013-02-04
  • 1970-01-01
  • 2013-03-17
  • 1970-01-01
  • 1970-01-01
  • 2014-04-07
  • 1970-01-01
相关资源
最近更新 更多