首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在两种模式之间打印行,包括还是独占(在sed、AWK或Perl中)?

如何在两种模式之间打印行,包括还是独占(在sed、AWK或Perl中)?
EN

Stack Overflow用户
提问于 2016-08-16 10:40:13
回答 8查看 93.4K关注 0票数 88

我有一个类似于下面的文件,我想打印两种给定模式PAT1PAT2之间的线条。

代码语言:javascript
运行
复制
1
2
PAT1
3    - first block
4
PAT2
5
6
PAT1
7    - second block
PAT2
8
9
PAT1
10    - third block

我读过如何在使用awk/sed时多次出现的两个标记模式之间选择行?,但我很好奇地看到所有可能的组合,包括或排除模式。

如何打印两种模式之间的所有线条?

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2016-08-16 10:40:13

PAT1和PAT2之间的打印线

代码语言:javascript
运行
复制
$ awk '/PAT1/,/PAT2/' file
PAT1
3    - first block
4
PAT2
PAT1
7    - second block
PAT2
PAT1
10    - third block

或者,使用变量:

代码语言:javascript
运行
复制
awk '/PAT1/{flag=1} flag; /PAT2/{flag=0}' file

这是怎么回事?

  • /PAT1/与具有此文本的行匹配,也与/PAT2/匹配。
  • /PAT1/{flag=1}在一行中找到文本PAT1时设置PAT1
  • 当在一行中找到文本/PAT2/{flag=0}时,flag会取消设置。
  • flag是一个默认操作的模式,即print $0:如果flag为1,则打印行。通过这种方式,它将打印从PAT1发生到看到下一个PAT2的所有行。这还将打印从最后一次PAT1匹配到文件末尾的行。

PAT1和PAT2之间的打印线--不包括PAT1和PAT2

代码语言:javascript
运行
复制
$ awk '/PAT1/{flag=1; next} /PAT2/{flag=0} flag' file
3    - first block
4
7    - second block
10    - third block

这使用next跳过包含PAT1的行,以避免打印。

这个对next的调用可以通过重新设置块:awk '/PAT2/{flag=0} flag; /PAT1/{flag=1}' file来删除。

PAT1和PAT2之间的打印行--包括PAT1

代码语言:javascript
运行
复制
$ awk '/PAT1/{flag=1} /PAT2/{flag=0} flag' file
PAT1
3    - first block
4
PAT1
7    - second block
PAT1
10    - third block

通过将flag放在最末尾,它将触发在PAT1或PAT2上设置的操作:在PAT1上打印,而不是在PAT2上打印。

PAT1和PAT2之间的打印行--包括PAT2

代码语言:javascript
运行
复制
$ awk 'flag; /PAT1/{flag=1} /PAT2/{flag=0}' file
3    - first block
4
PAT2
7    - second block
PAT2
10    - third block

通过将flag放在最开始的位置,它将触发先前设置的操作,从而打印结束模式,而不是开始模式。

PAT1和PAT2之间的打印行--如果没有发生其他PAT2,则不包括从最后一个PAT1到文件末尾的行

这是基于埃德·莫顿的一个解决方案的。

代码语言:javascript
运行
复制
awk 'flag{
        if (/PAT2/)
           {printf "%s", buf; flag=0; buf=""}
        else
            buf = buf $0 ORS
     }
     /PAT1/ {flag=1}' file

作为一条单线:

代码语言:javascript
运行
复制
$ awk 'flag{ if (/PAT2/){printf "%s", buf; flag=0; buf=""} else buf = buf $0 ORS}; /PAT1/{flag=1}' file
3    - first block
4
7    - second block

# note the lack of third block, since no other PAT2 happens after it

这会将所有选定的行保存在一个缓冲区中,从找到PAT1时开始填充。然后,它将一直填充以下行,直到找到PAT2为止。在这一点上,它打印存储的内容并清空缓冲区。

票数 134
EN

Stack Overflow用户

发布于 2016-08-16 13:10:08

使用grep与PCRE (在可用的情况下)使用打印标记和标记之间的行

代码语言:javascript
运行
复制
$ grep -Pzo "(?s)(PAT1(.*?)(PAT2|\Z))" file
PAT1
3    - first block
4
PAT2
PAT1
7    - second block
PAT2
PAT1
10    - third block
  • -P perl-regexp,PCRE.不是所有的grep变体
  • -z将输入视为一组行,每一行以零字节结尾,而不是以换行符结尾。
  • -o只打印匹配
  • (?s) DotAll .点也能找到新行。
  • (.*?)非贪婪查找
  • \Z只匹配字符串的末尾,或尾的换行符之前。

标记之间的打印行(不包括末端标记)

代码语言:javascript
运行
复制
$ grep -Pzo "(?s)(PAT1(.*?)(?=(\nPAT2|\Z)))" file
PAT1
3    - first block
4
PAT1
7    - second block
PAT1
10    - third block
  • (.*?)(?=(\nPAT2|\Z))非贪婪查找\nPAT2\Z

不包括标记的标记之间的打印行

代码语言:javascript
运行
复制
$ grep -Pzo "(?s)((?<=PAT1\n)(.*?)(?=(\nPAT2|\Z)))" file
3    - first block
4
7    - second block
10    - third block
  • (?<=PAT1\n)PAT1\n的正向跟踪

标记之间的打印行不包括起始标记

代码语言:javascript
运行
复制
$ grep -Pzo "(?s)((?<=PAT1\n)(.*?)(PAT2|\Z))" file
3    - first block
4
PAT2
7    - second block
PAT2
10    - third block
票数 11
EN

Stack Overflow用户

发布于 2019-04-20 12:16:56

为了完整起见,这里有一个Perl解决方案:

PAT1和PAT2之间的打印行-包括PAT1和PAT2

代码语言:javascript
运行
复制
perl -ne '/PAT1/../PAT2/ and print' FILE

或者:

代码语言:javascript
运行
复制
perl -ne 'print if /PAT1/../PAT2/' FILE

PAT1和PAT2之间的打印行-排除PAT1和PAT2

代码语言:javascript
运行
复制
perl -ne '/PAT1/../PAT2/ and !/PAT1/ and !/PAT2/ and print' FILE

或者:

代码语言:javascript
运行
复制
perl -ne 'if (/PAT1/../PAT2/) {print unless /PAT1/ or /PAT2/}' FILE 

PAT1和PAT2之间的打印行-仅排除PAT1

代码语言:javascript
运行
复制
perl -ne '/PAT1/../PAT2/ and !/PAT1/ and print' FILE

PAT1和PAT2之间的打印行-仅排除PAT2

代码语言:javascript
运行
复制
perl -ne '/PAT1/../PAT2/ and !/PAT2/ and print' FILE

另请参阅:

  • 有关perldoc perlop语法的更多信息,请参见/PAT1/../PAT2/中的Range运算符部分:

距离算子 ...In标量上下文,“.”返回布尔值。操作符是双稳态的,就像触发器一样,并模拟sed、awk和各种编辑器的行范围(逗号)操作符。

  • 有关-n选项,请参见perldoc perlrun,它使Perl的行为类似于sed -n
  • Perl Cookbook,6.8详细讨论了提取范围的线条。
票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38972736

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档