【问题标题】:awk retain adjacent line based on duplicate fieldawk 根据重复字段保留相邻行
【发布时间】:2017-02-01 15:43:50
【问题描述】:

我正在处理 tshark 字段的一些输出。一些处理已经发生,现在有相邻的行,其中最后一个字段是重复的。这些重复项缺少具有匹配序列号的行。任务是只保留序列列匹配的相邻行对。最后一个字段的值是 0 和 130,每对行都以 130 开头。序列是一个 0-15 的数字。数据流包含许多行。 这些字段是:

date       time                 src-int dst-int seq     function
24/01/2017 16:57:27.307400000   10      1000    11      130
24/01/2017 16:57:27.418675000   1000    10      11      0
24/01/2017 16:58:53.603604000   1000    10      12      0
24/01/2017 16:58:54.121603000   10      1000    13      130
24/01/2017 16:58:54.677752000   10      1000    14      130
24/01/2017 16:58:54.681079000   1000    10      14      0
24/01/2017 17:09:12.974979000   10      1000    1       130
24/01/2017 17:09:12.981149000   1000    10      1       0
24/01/2017 17:09:13.477211000   1000    10      2       0
24/01/2017 17:09:14.026279000   1000    10      3       0

所需的输出是保留具有函数顺序 130 然后 0 和匹配序列号的行对:

24/01/2017 16:57:27.307400000   10      1000    11      130
24/01/2017 16:57:27.418675000   1000    10      11      0
24/01/2017 16:58:54.677752000   10      1000    14      130
24/01/2017 16:58:54.681079000   1000    10      14      0
24/01/2017 17:09:12.974979000   10      1000    1       130
24/01/2017 17:09:12.981149000   1000    10      1       0

我有一个成功的解决方案。它匹配\t130$ 并获取下一行,如果序列匹配则打印。它返回了良好的数据,但它不处理 130 的重复值。在示例数据中,它省略了序列 14。相邻重复行的数量是任意的,因此嵌套另一个测试似乎很愚蠢。

awk "/\t130$/ {seq=$5; prev=$0; getline;} $5==seq {print prev; print;}"

如何最好地处理开始条件下的所有重复项?

顺便说一句,在 Windows 7 中使用 GNU awk。 FWIW 两行最终将使用print prev,$0 连接,为清楚起见未显示。

【问题讨论】:

    标签: awk duplicates


    【解决方案1】:
    awk 'NR==1 { print; next } 
        $6 == 0 && $5 == seq && c == 0 { print row; print; c++ }
        $6 == 130 { seq=$5; row=$0; c=0 }
    ' file
    date       time                 src-int dst-int seq     function
    24/01/2017 16:57:27.307400000   10      1000    11      130
    24/01/2017 16:57:27.418675000   1000    10      11      0
    24/01/2017 16:58:54.677752000   10      1000    14      130
    24/01/2017 16:58:54.681079000   1000    10      14      0
    24/01/2017 17:09:12.974979000   10      1000    1       130
    24/01/2017 17:09:12.981149000   1000    10      1       0
    

    【讨论】:

    • 谢谢,我喜欢它并且很容易修改以连接行。NR==1 { print; next } 的目的是什么?在给定的输入上使用此解决方案会导致省略 seq 11 函数 0 的行。如果我删除 NR==1 部分,它可以正常工作。
    • @gloopy NR==1 部分仅用于打印标题。如果不需要,您可以删除它
    • 啊。标题行仅用于问题描述:)
    • 此答案在查找下一个 130 之前,匹配任何以 0 结尾的行与匹配的序列号,并且不严格执行相邻行的要求。它适用于数据集,细微的差异可能非常有用。
    • @gloopy 我添加了相邻行要求
    【解决方案2】:
    $ awk 'p==$5 && q==130 && $6==0 {print b $0} {p=$5; q=$6; b=$0 "\n"}' file
    24/01/2017 16:57:27.307400000   10      1000    11      130
    24/01/2017 16:57:27.418675000   1000    10      11      0
    24/01/2017 16:58:54.677752000   10      1000    14      130
    24/01/2017 16:58:54.681079000   1000    10      14      0
    24/01/2017 17:09:12.974979000   10      1000    1       130
    24/01/2017 17:09:12.981149000   1000    10      1       0
    
    • p 是以前的$5,应该与当前的$5 相同
    • q 是以前的$6,应该是 130
    • b 缓冲前一个 $0 并附加一个 \n 用于漂亮的 print

    【讨论】:

    • 谢谢。关于流程,我相信第二个{action} 总是执行,因为它没有条件?在这种情况下为什么要清除 b?另外,有什么理由追加行尾而不是使用两个打印语句?
    • 1.邋遢。 2. 不具体。
    • 此答案强制匹配必须在相邻行中。标记为正确,因为它最适合问题。
    猜你喜欢
    • 1970-01-01
    • 2012-10-31
    • 1970-01-01
    • 2020-03-28
    • 1970-01-01
    • 2017-10-13
    • 1970-01-01
    • 2018-06-10
    • 1970-01-01
    相关资源
    最近更新 更多