Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 找到两个中间正好有'n'行的匹配项_Linux_Awk_Grep_Sed - Fatal编程技术网

Linux 找到两个中间正好有'n'行的匹配项

Linux 找到两个中间正好有'n'行的匹配项,linux,awk,grep,sed,Linux,Awk,Grep,Sed,在我的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,patte

在我的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来做到这一点,但我想知道这些实用工具是否也能做到这一点

多谢各位

这是我在读了@Barmar的答案后尝试的

awk -v n=2 '/pat1/ { first = NR } 
           !/pat3/ 
            /pat2/ && first && NR - first == n { count++ } END {print count}'
但我仍然没有正确地理解它。我需要在四种情况下执行此操作:

  • pat1
    pat3
    是相同的
  • pat2
    pat3
    是相同的
  • 这三种模式都是相同的
  • 没有两个是相同的
下面是带有附加
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
以避免将同一行视为
pat1
pat3
匹配

在你的尝试中,这条线

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

我认为你需要找到一个awk教程来学习awk的基本操作模型。我不会在这里教你,这不是一个辅导网站。

有:

一些解释:

if (pat1 matches) {                     #  /pat1/{
     read and append 2 lines            #  N;N;
     if (pat2 matches after 2 '\n's) {  #  /\([^\n]*\n\)\{2\}.*pat2/ {
          if (pat3 does not match) {    #  /pat3/!
             print                      #  p
          }                             
      }                                 #  }
 }                                      #  }

+非常感谢Barmar!我真的很遗憾,我错过了一个重要的要求。请你再看一眼好吗?也许是你开始为自己编程的时候了,这就是你学习的方式。根据我的代码,添加第三个check.awk-vn=2'/pat1/{first=NR}应该很容易/pat3//pat2/&&first&&NR-first==n{count++}END{print count}当
模式1
模式3
可以相同时,我遇到了问题,这意味着模式1不再出现在
模式1
模式2
之间,我无法在注释中读取您的代码,你应该把它贴在问题上。当一些模式可以相同时,它也变得更加棘手。您需要设置变量来跟踪状态。模式可以任意重叠吗?特别是,您是否可以,例如,
pat1/pat1/pat2
?@QiangLi从上述样本数据中您的预期输出是什么,这样更容易理解您的需求。+1。谢谢!你能给一些关于这些命令的详细解释吗?添加了一些细节,希望这有帮助
sed -ne '/pat1/{N;N;/\([^\n]*\n\)\{2\}.*pat2/{/pat3/!p}}' input
if (pat1 matches) {                     #  /pat1/{
     read and append 2 lines            #  N;N;
     if (pat2 matches after 2 '\n's) {  #  /\([^\n]*\n\)\{2\}.*pat2/ {
          if (pat3 does not match) {    #  /pat3/!
             print                      #  p
          }                             
      }                                 #  }
 }                                      #  }