awk处理单行,其中以分号分隔的字段因RS而失败

时间:2016-09-17 16:35:10

标签: bash awk

我有一个名为strg.cfg的文件,内容为

iMac;1;1;37;;Monitor;1;1;0;;Thunderbolt;1;0;0;;TimeMachine;0;0;0;;USB;1;0;0;;Lacie Stereo;0;0;0;;Rland MacMini;0;0;0;;Scanner;0;0;0;;end

记录以两个分号分隔;;和一个分号的字段。 我尝试使用以下awk文件处理此文件

BEGIN {FS=";"; RS="/\;\;/"}
{ print $1 ", " $2 ", " $3 ", " $6 }

$ 6用作测试,因为如果它工作,它不应该打印任何东西,因为它只有四个字段。 但这似乎不起作用,好像RS =根本没有被考虑在内。它仍将始终将整行​​视为记录。 以6美元打印“监视器”而不打印其他行。

2 个答案:

答案 0 :(得分:1)

你没有显示预期的输出,所以我们只是猜测,但这是你想要的吗?

$ cat tst.awk
BEGIN {FS=";"; OFS=", "; RS=";;"}
RT{ print $1, $2, $3, $6 }

$ awk -f tst.awk file
iMac, 1, 1,
Monitor, 1, 1,
Thunderbolt, 1, 0,
TimeMachine, 0, 0,
USB, 1, 0,
Lacie Stereo, 0, 0,
Rland MacMini, 0, 0,
Scanner, 0, 0,

以上使用GNU awk进行多字符RS和RT。如果您没有GNU awk,那么最简单的解决方案是首先将;;转换为通常的RS(\ n):

awk '{gsub(/;;/,"\n")}1' file | awk '....'

但如果您宁愿避免2个awk调用和管道,那么您可以这样做:

$ cat tst.awk
BEGIN {FS=";"; OFS=", "; RS=";"}
/^$/ {
    $0 = rec
    rec = ""
    print $1, $2, $3, $6
    next
}
{ rec = (rec ? rec FS : "") $0 }

$ awk -f tst.awk file
iMac, 1, 1,
Monitor, 1, 1,
Thunderbolt, 1, 0,
TimeMachine, 0, 0,
USB, 1, 0,
Lacie Stereo, 0, 0,
Rland MacMini, 0, 0,
Scanner, 0, 0,

答案 1 :(得分:0)

Awk结合了不同的命令。如果您只想在选择字段之前用新行替换;;,则可以执行

sed 's/;;/;\n/g' strg.cfg | cut -d";" -f1,2,3,6

或替换结果中的一些内容

sed 's/;;/;\n/g' strg.cfg | cut -d";" -f1,2,3,6 | sed 's/;/, /g'