首先检查下3行后如何删除行

时间:2019-05-17 10:48:11

标签: awk sed text-manipulation

我有一个与此相似的文本文件

00:00:24.752
8,594
3,847
0
00:00:25.228
0
1,692
0
00:00:25.738
6,548
5,304
0
00:00:26.248
1,807
417
0
00:00:26.758
3,913
5,335
0
00:00:26.792
0
00:00:27.234
0
00:00:27.268
0
0
0
00:00:27.778
9,903
2,345
0
00:00:27.812
0
00:00:28.322
0
9,501
0

这是网络流量,第一部分是时间戳,而后两个部分是发送和接收的流量。第三个是零,我不知道为什么会出现。
因此,我的目标是仅保留至少具有发送/接收流量值的行,并且每次都删除第三个0。所以我会有这样的结果。

00:00:24.752
8,594
3,847
00:00:25.228
0
1,692
00:00:25.738
6,548
5,304
00:00:26.248
1,807
417
00:00:26.758
3,913
5,335
00:00:27.778
9,903
2,345
00:00:28.322
0
9,501

尝试使用awk来检查当前行的长度,并且如果该行少于8个字符,则打印该行和下一个2。但是由于文件在执行之后并不总是具有至少2个值时间戳记无法正常工作。

3 个答案:

答案 0 :(得分:2)

awk '
/[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}/ {
  if (NR > 1) p() 
  i = 0
}
{ buf[++i] = $0 }
END { p() }
function p() {
  if (buf[2] || buf[3]) {
    print buf[1]
    print buf[2]
    print buf[3]
  }
  delete buf
}' file

p是一个函数,如果其中第2和第3位不为空或为零,则打印该行并清除缓冲区。每当看到时间戳记(不是文件的第一行)并且命中EOF时,都会调用它。因此,上面的脚本基本上缓冲了两个时间戳之间的行,如果满足以下条件:在时间戳之后至少应有两行,并且它们不应为零,则打印它们。

答案 1 :(得分:0)

这可能对您有用(GNU sed):

sed '/:/!{H;$!d};x;/\n.*\n.*\n/{/\n0\n0\n0/!s/\n0$//p};x;h;d' file

如果当前行不是时间戳(不包含:),请将其附加到保留空间;如果不是最后一行,则将其删除。

如果当前行是最后一行或时间戳记,请交换到保留空间,并检查上一条记录是否包含4行,并且最后3行未清零,如果是,则删除记录的最后一行并打印修改后的记录。

交换回模式空间,将保留空间替换为当前行(时间戳)并删除它。

删除行后,当前行将不再进行sed处理。

答案 2 :(得分:0)

如果要忽略所有第4行,请使用awk脚本来实现:

awk 'RN % 4{print}' input.txt

具有所需输出的结果。