linux - 找到两个匹配项,它们之间正好有 `n` 行

标签 linux awk grep

在我的 Linux 终端中,我需要找出这种情况出现的次数,其中 pattern 1pattern 2 出现在正好是 n< 的两行中 行分开,附加要求 pattern 3 不能出现在任何这些 n 行中。 例如,如果我有一个文本文件

...
a
* pat1 **
b
c
** pat2 ****
* pat1 **
b
** pat2 ****
*******pat1**
efda
*pat3****
**pat2********
...

n=2pattern 1pat1时,pattern 2pat2,而pattern 3pat3,那么只有1次出现。

如何在 awkgrep(或其姐妹)等实用工具中方便地执行此操作。我知道如何使用 python 或 perl 来执行此操作,但只是想知道这些实用工具是否可以做同样的事情。

谢谢。

这是我在阅读@Barmar 的回答后尝试的

awk -v n=2 '/pat1/ { first = NR } 
           !/pat3/ 
            /pat2/ && first && NR - first == n { count++ } END {print count}'

但是我还是没看对。我需要针对四种情况执行此操作:

  • pat1pat3 是一样的。
  • pat2pat3 是一样的。
  • 所有这三种模式都是相同的。
  • 其中没有两个是相同的。

最佳答案

awk -v n=2 '/pat1/ { first = NR }
            /pat2/ && first && NR - first == n { count++ }
            END {print count}'

这是带有附加 pat3 要求的代码:

awk -v n=2 '/pat3/ && first { pat3 = 1; first = 0 }
            /pat1/ && !pat3 { first = NR }
            /pat2/ && first && NR - first == n { count++; first = 0 }
            END {print count}'

我认为这适用于所有相同模式的组合,但我还没有测试过。当模式可以相同时,之所以会出现这种技巧,是因为与脚本中的一个测试匹配的行不会阻止它通过其余测试。因此脚本必须重置状态变量 pat3first 以避免将同一行同时作为 pat1pat3匹配。

在你的尝试中,这条线

!/pat3/

什么都不做。首先,它在语法上是不正确的——每个测试都需要跟在一个语句或 block 之后,说明匹配时要做什么。其次,即使你在它后面放一个空 block ,也只是意味着“如果当前行不匹配 pat3,什么都不做”。它对脚本中其他模式匹配的行为没有任何影响。

我觉得你需要找一个awk教程来学习awk的基本运行模型。我不会在这里教你,这不是辅导网站。

关于linux - 找到两个匹配项,它们之间正好有 `n` 行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17417094/

相关文章:

regex - 填充空间/制表符分隔,空列为0

bash - 如何从文本文件中删除部分重复项?

macos - Grep 文件搜索返回 : Is a directory in OSX Mountain Lion

linux - Linux 中大型 TSV 的条件编辑

linux - linux删除重复文件的方法

linux - 松弛 curl 不起作用

linux - 列中出现整数 - 添加为新列

通过树莓派切换套接字状态的Java函数

c - 如何从子进程向父进程写入值?

awk - 如何用awk合并两个文件?