我有以下文件:
$ cat disk.out
disk0
fcs0
text
text
text
disk1
fcs1
text
text
text
text
...
我想要实现的是匹配“disk”+“fcs”,然后在一行中打印这一对,如下所示:
disk0,fcs0
disk1,fcs1
...
所以我将“disk”和“fcs”匹配并将awk
输出记录分隔符更改为“,”。`
$ awk '/disk|fcs/' ORS="," disk.out
disk0,fcs0,disk1,fcs1,
问题是,它会将所有匹配打印在一行上,并带有尾随,
.如何在一行中仅打印每场比赛?像这样:
disk0,fcs0
disk1,fcs1
...
答案1
您必须保存“disk”行(不打印它),直到找到下一个“fcs”行:
awk '/disk/{ DISK=$0; next } /fcs/{ print DISK "," $0 }'
你的方法的问题是它打印任何一个匹配“disk”或“fcs”的行,不带结合那些行。
编辑:sp asic的脚本更稳健,因为它忽略了
disk3
text
fcs3
在这种情况下,我的脚本会很乐意打印“disk3,fcs3”。
答案2
$ awk '/fcs/ && a ~ /disk/ {print a","$0} {a=$0}' disk.out
disk0,fcs0
disk1,fcs1
string ~ /regexp/
将检查正则表达式(此处)是否与给定字符串匹配,在本例中disk
该字符串是可变的。这里使用a
运算&&
符来组合两个条件,只有第一个条件/fcs/
和第二个条件a ~ /disk/
都为真时,才会执行打印。
答案3
如果它始终采用这种格式(一个磁盘一个 fcs,fcs 始终在磁盘之后),您可以不用awk
:
grep -F -e disk -e fcs file | paste -d , - -
或者:
awk '(/disk/ && ORS=",") || (/fcs/ && ORS=RS)' file
尽管使用awk
,您可能更喜欢 Martin 或 sp asic 给出的更清晰的方法。