首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Bash:如何确定行,但排除某些行之间的行?

Bash:如何确定行,但排除某些行之间的行?
EN

Stack Overflow用户
提问于 2019-05-31 02:48:34
回答 1查看 395关注 0票数 0

我有一个如下所示的文件:

a: 0
a: 0
a: 0
a: 1
b: 1
c: 1
d: 1
e: 1
f: 1
a: 2
b: 2
c: 2
d: 2
e: 2
f: 2
a: 3
b: 3
c: 3
d: 3
e: 3
f: 3
c: 4
c: 4
c: 4

我希望捕获并输出表单<a line><anything other than an a or c line><c line>的所有ac行,因此输出将如下所示:

a: 1
c: 1

a: 2
c: 2

a: 3
c: 3

请注意,开头的a: 0行和结尾的c: 4行都不会被捕获,因为它们不遵循我提到的模式。另请注意,删除了ac行之间的b行。

我一直在尝试使用Bash的pcregrep来做这件事,但是还没有找到解决方案。有什么想法吗?

谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-05-31 03:12:35

使用awk

尝试:

$ awk -F: '$1=="a"{aline=$0} $1=="c"{if(aline)print aline ORS $0 ORS; aline=""}' file
a: 1
c: 1

a: 2
c: 2

a: 3
c: 3

它是如何工作的

默认情况下,awk一次读入一行。

  • -F:

这将告诉awk使用:作为字段separator.

  • $1=="a"{aline=$0}

每次观察到a行时,将该行保存在变量aline.

  • $1=="c"{if(aline)print aline ORS $0 ORS; aline=""}

每次观察到c行时,检查是否有一个非空的aline。如果是,则打印aline和当前行,并用换行符分隔。另外,将aline设置回空字符串。

多行版本

对于那些喜欢将命令分散到多行的用户:

awk -F: '
    $1=="a"{
        aline=$0
    }

   $1=="c"{
        if(aline)
            print aline ORS $0 ORS
        aline=""
    }' file

使用sed

$ sed -n '/^a/h; /^c/{x;/^a/{p;x;s/$/\n/;p};h}' file
a: 1
c: 1

a: 2
c: 2

a: 3
c: 3

它是如何工作的

  • -n

这将告诉sed不打印任何内容,除非我们显式地请求它to.

  • /^a/h

每当我们有以a开头的行时,我们都会将其保存到hold space.

  • /^c/{ x; /^a/{ p; x; s/$/\n/; p}; h}

任何时候我们有一个以c开头的行,我们:

- We swap (`x`) the pattern space with the hold space.
- If the new pattern space starts with `a`, then we print (`p`) it, and swap (`x`) again, add a new line to the end of the new pattern space (`s/$/\n/`) and print (`p`) it.
- Lastly we save the current pattern space (which starts with a `c`) to the hold space.

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56383997

复制
相关文章

相似问题

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