我有一个看起来像这样的文件:
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
行均未捕获,因为它们没有遵循我提到的模式。还请注意,b
和a
行之间的c
行已删除。
我一直在尝试使用Bash的pcregrep进行环视,但尚未找到解决方案。有什么想法吗?
谢谢!
答案 0 :(得分:4)
尝试:
$ 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 -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
开头)保存到保留空间。