我有一个如下所示的文件:
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>
的所有a
和c
行,因此输出将如下所示:
a: 1
c: 1
a: 2
c: 2
a: 3
c: 3
请注意,开头的a: 0
行和结尾的c: 4
行都不会被捕获,因为它们不遵循我提到的模式。另请注意,删除了a
和c
行之间的b
行。
我一直在尝试使用Bash的pcregrep来做这件事,但是还没有找到解决方案。有什么想法吗?
谢谢!
发布于 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.
https://stackoverflow.com/questions/56383997
复制相似问题