Bash:如何对某些行进行某些行,但排除其中的某些行?



我有一个看起来像这样的文件:

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行和c<a line><anything other than an a or c line><c line>,因此输出如下所示:

a: 1
c: 1
a: 2
c: 2
a: 3
c: 3

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

我一直在尝试使用 Bash 的 pcregrep 进行环顾四周,但尚未找到解决方案。有什么想法吗?

谢谢!

使用 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 使用:作为字段分隔符。

  • $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 不要打印任何东西,除非我们明确要求它。

  • /^a/h

    每当我们有一行以a开头 ,我们将其保存到保留空间。

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

    每当我们有一行以c开头时,我们:

    • 我们将模式空间与保持空间交换(x)。

    • 如果新的图案空间以a开头,那么我们打印(p)它,并再次交换(x),在新图案空间(s/$/n/)的末尾添加新行并打印(p)它。

    • 最后,我们将当前模式空间(以c开头)保存到保持空间。

相关内容

  • 没有找到相关文章

最新更新