在我的linux终端中,我需要找到这样的出现次数,其中pattern 1
和pattern 2
出现在两行中,这两行正好相隔n
行,另外还要求pattern 3
不能出现在这些n
行中。
例如,如果我有一个文本文件
...
a
* pat1 **
b
c
** pat2 ****
* pat1 **
b
** pat2 ****
*******pat1**
efda
*pat3****
**pat2********
...
当
n=2
和pattern 1
是pat1
时,pattern 2
是pat2
且pattern 3
是pat3
时,则只有1次出现。如何在诸如
awk
、grep
(或其姐妹)等实用工具中方便地执行此操作。我知道如何使用python或perl来执行此操作,但只是想知道这些实用工具是否可以执行相同的操作。谢谢您。
这是我读了《巴尔玛的回答》后所做的尝试
awk -v n=2 '/pat1/ { first = NR }
!/pat3/
/pat2/ && first && NR - first == n { count++ } END {print count}'
但我还是没有正确理解。我需要在四种情况下这样做:
pat1
和pat3
是相同的。pat2
和pat3
是相同的。这三种模式都是一样的。
没有两个是一样的。
最佳答案
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}'
我认为这对所有模式的组合都是一样的,但我还没有测试过。当模式可以是相同的时,这个技巧的原因是脚本中匹配一个测试的行并不能阻止它通过剩余的测试。因此,脚本必须重置状态变量
pat3
和first
,以避免将同一行视为pat1
和pat3
匹配。在你的尝试中
!/pat3/
什么都不做。首先,它在语法上是不正确的——每个测试之后都需要一个语句或块来说明匹配后该做什么。第二,即使你在后面放了一个空块,也就是说“如果当前行与pat3不匹配,不要做任何事情”。它对脚本中其他模式匹配的行为没有任何影响。
我认为你需要找一个awk教程来学习awk的基本操作模型。我不会在这里教你的,这不是辅导网站。
关于linux - 找到两个匹配项,且两者之间的行正好是'n`行,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17417094/