首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Bash one liner如果字符串匹配,则从文件获取行组

Bash one liner如果字符串匹配,则从文件获取行组
EN

Stack Overflow用户
提问于 2016-01-21 20:20:18
回答 2查看 88关注 0票数 1

我有一个类似的日志文件;

代码语言:javascript
复制
A
some lines
some lines
Z
A
some lines
some lines
IMPORTANT text
some lines
Z
A
some lines
more lines
some lines
Z
A
some lines
IMPORTANT text
more lines
some lines
Z

我只需要A-Z之间的行,如果它有重要的字.因此,期望的输出是;

代码语言:javascript
复制
A
some lines
some lines
IMPORTANT text
some lines
Z
A
some lines
IMPORTANT text
more lines
some lines
Z

A之间的行数是可变的.我尝试了太多的命令,比如:

代码语言:javascript
复制
grep 'IMPORTANT' -A 3 -B 3 x.log | sed -n '/^A$/,/^Z$/p'
grep 'IMPORTANT' -A 3 -B 3 x.log | grep -E '^Z$' -B 5 | grep -E '^A$' -A 5

有些印刷不需要从另一组,其他印刷线没有起点或终点..。都失败了。

有办法用一个班轮吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-01-21 20:36:47

使用gnu-awk您可以这样做:

代码语言:javascript
复制
awk 'BEGIN{RS=ORS="\nZ\n"} /^A/ && /IMPORTANT/' file
A
some lines
some lines
IMPORTANT text
some lines
Z
A
some lines
IMPORTANT text
more lines
some lines
Z
  • BEGIN{RS=ORS="\nZ\n"}将输入和输出记录分隔符设置为Z,两边都有换行符。
  • /^A/ && /IMPORTANT/确保每个记录都以A开头,并在其中包含IMPORTANT
  • 每个匹配都是打印出来的,因为这是awk中的默认操作。
票数 5
EN

Stack Overflow用户

发布于 2016-01-21 20:31:32

使用sed:

代码语言:javascript
复制
sed -n '/^A$/{:a;N;/\nZ$/!ba;/IMPORTANT/p}' x.log

解释:

代码语言:javascript
复制
/^A$/ {            # If line matches ^A$...
    :a             # Label to branch to
    N              # Append next line to pattern space
    /\nZ$/!ba      # Branch to :a if pattern space doesn't end with \nZ
    /IMPORTANT/p   # Print if pattern space contains IMPORTANT
}

这基本上是附加行,直到我们在模式空间中有一个完整的块,然后如果它与IMPORTANT匹配,就打印它,否则就丢弃它。

当我们到达循环结束时,-n选项会阻止输出。

有些seds不支持带有命令分组({};)或内联注释的oneliners。对于某些seds,让p;而不是p工作,而对于另一些seds,这(基本上是上面的减注释)应该可以工作(并且符合POSIX ):

代码语言:javascript
复制
sed -n '/^A$/{
    :a
    N
    /\nZ$/!ba
    /IMPORTANT/p
}' x.log
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34933553

复制
相关文章

相似问题

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