简体   繁体   English

awk处理单行,其字段由分号分隔,RS失败

[英]awk processing single line with fields separated by semicolons failing with RS

I have a file called strg.cfg with the content 我有一个名为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

The records are separated by two semicolons ;; 记录由两个分号分隔; and the fields by a single semicolon. 和字段由一个分号组成。 I tried to process this file with the following awk file 我尝试使用以下awk文件处理此文件

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

$6 is used as a test since if it works it shouldn't print anything for that since it's only four fields. $ 6被用作测试,因为如果它可以工作,那么它就不会打印任何内容,因为它只有四个字段。 But that doesn't seem to work, as if the RS= is not taken into consideration at all. 但这似乎不起作用,好像根本没有考虑RS =一样。 It will always still see the whole line as the record. 它将始终始终将整个行视为记录。 Printing "Monitor" for $6 and not printing other lines. 以6美元的价格打印“显示器”,而不打印其他行。

You don't show the expected output so we're left guessing but is this what you want? 您没有显示预期的输出,因此我们只能猜测,这是您想要的吗?

$ 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,

The above uses GNU awk for multi-char RS and RT. 上面使用GNU awk进行多字符RS和RT。 If you don't have GNU awk then the simplest solution is to convert the ;; 如果您没有GNU awk,那么最简单的解决方案是转换;; s to the usual RS (\\n) first: s到通常的RS(\\ n)首先:

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

but if you'd rather avoid the 2 awk calls and pipe then you can do this: 但是,如果您不想使用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,

Awk combines different commands. Awk组合了不同的命令。 When you just want to replace ;; 当您只想替换;; by a new line before selecting fields, you can do 在选择字段之前用新的一行

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

or replace some stuff in the result 或替换结果中的某些内容

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM