awk

awk

类似,但不完全一样如何选择两个模式(包括它们)之间的第一次出现...给定这个输入文件:

something P1 something
content1
content2
something P1 something
content3
content4

我只需要这个输出:

something P1 something
content1
content2

答案1

awk 解决方案:

 awk '/^something P1 something$/{if(++i>1)exit} i' input_file

这将打印第一行匹配/^something P1 something$/和所有行,直到下一行匹配该模式(但不包括该行)或文件末尾。

答案2

我怀疑这就是你真正想要的:

打印第一个块:

$ awk '$0=="something P1 something"{c++} c==1' file
something P1 something
content1
content2

或打印第二个:

$ awk '$0=="something P1 something"{c++} c==2' file
something P1 something
content3
content4

等等。如果没有明确的要求说明,这只是一个猜测。

答案3

 $ sed -ne '
     /P1/!d
     :loop
        p;n
     //!bloop
     q
 ' file 

结果:

something P1 something1
content1
content2

使用带有非 Posix 构造 Q 的 Gnu sed 编辑器:

$ sed -e '
   /P1/,/P1/!d
   //!{$q;b;}
   G;/\n./Q;s/\n.*//;h
' file

对于 Posix only 构造,我们这样做:

 $ sed -ne '
      /P1/,/P1/!d
      //!{
        p;$q;d
      }
      G;/\n./q;s/\n.*//p;h
 ' file

使用 Perl :

$ perl -lne '
    next unless $e = /P1/ ... /P1/;
    $e =~ /E/ ? last : print;
' file

完后还有:

$ perl -0777 -pe '$_ = /^(.*?P1(?s:.*?\n))(?=.*?P1)/m ? $1 : $,' file

答案4

awk

ith 模式的通用解决方案堵塞在 awk 中是:

awk -v i=1 -v pat='something P1 something'    '$0~pat{i--}i==0'

解释:

-v i=1        # sets the pattern block to print (1 in this case).
-v pat='...'  # sets the regex pattern that will be tested.

$0~pat        # tests if the input line match the pattern
{i--}         # If the pattern was found, reduce the count.
i==0          # If the count has reduced to 0, print the block lines.

如果重要的模式只是 P1,则使用:

awk -v i=1 -v pat='P1' '$0~pat{i--}i==0'

为了更快地执行,请在块结束时退出:

awk -v i=1 -v pat='P1' '$0~pat{i--}i==0;i<0{exit}'

如果你想要一个文字匹配(不是模式),使用:

awk -v i=1 -v pat='P1' '$0 == pat {i--}; i==0; i<0{exit}'

sed

要从第一的一个模式的实例到下一个模式的实例,您可以在 GNU sed 中执行以下操作:

sed -n '/something P1 something/!b;b2;:1;{/something P1 something/q;:2;p;n;b1}'

第一行之前可能有一些行something P1 something
当找到第二个模式时,脚本会(快速)停止。

由于两种模式(开始和结束)相同,我们可以将命令简化为:

sed -n -e '/something P1 something/!b;b2;:1;{//q;:2;p;n;b1}'

为了使其更加便携,请使用:

sed -n -e '/something P1 something/!{b' -e '};b2' -e ':1' -e '{//q;:2' -e 'p;n;b1' -e '}'

相关内容