Awk 如何在先检查下3行后删除行

Awk 如何在先检查下3行后删除行,awk,sed,text-manipulation,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,5

我有一个类似的文本文件

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个值,因此它无法正常工作

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时,就会调用它。所以上面的脚本基本上在两个时间戳之间缓冲行,如果它们满足时间戳之后至少应该有两行的条件,并且它们不应该为零,则打印它们

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

这可能适用于您(GNU-sed):

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

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

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

注意:删除一行时,当前行不会进行进一步的sed处理。

这可能适用于您(GNU sed):

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

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

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


注意:删除一行时,当前行不会进行进一步的sed处理。

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

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

结果与所需的输出一致。

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

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

结果与您期望的输出一致。

我尝试了与
awk-F,'length($1)<8{print F;print;getline;print}{F=$1}'
类似的方法,因此它会将时间戳与接下来的两行一起打印。但由于文件不一致,因此无法正常工作。另外,请添加为什么预期输出中没有
00:00:26.792
0等行,请编辑您的问题一次。@RavinderSingh13这不是期望的输出,因为他们没有提供额外的信息。那么请务必提及从期望的输出中删除它背后的逻辑?@RavinderSingh13我没有真正理解您在这里所说的。从预期输出中删除它背后的逻辑是,它们不提供我上面所说的附加信息。我只需要保留至少有一个接收/发送流量值的线路。尽管如此,还是感谢您花时间来帮助我。我已经尝试了类似于
awk-F,'length($1)<8{print F;print;getline;print}{F=$1}'
的方法,所以它会将时间戳与接下来的两行一起打印。但由于文件不一致,因此无法正常工作。另外,请添加为什么预期输出中没有
00:00:26.792
0等行,请编辑您的问题一次。@RavinderSingh13这不是期望的输出,因为他们没有提供额外的信息。那么请务必提及从期望的输出中删除它背后的逻辑?@RavinderSingh13我没有真正理解您在这里所说的。从预期输出中删除它背后的逻辑是,它们不提供我上面所说的附加信息。我只需要保留至少有一个接收/发送流量值的线路。尽管如此,还是要感谢您抽出时间来帮助我。如果您有时间,请简要解释。如果您有时间,请简要解释。