将 space 的第二列视为一列

Treat 2nd column with space as one column

我有一个命令具有以下示例的输出。

SAN_FR_9644T "Threat for Security" /vol/SAN44_39/SAN_FR_9644T-PPIE/Threat for Security
SAN_FR_3131T ZZ$        /vol/SAN44_39/SAN_FR_3131T-PPEL
SAN_FR_2281T "Control Line" /vol/SAN44_39/SAN_FR_2281T-PPF/33YShared/Control Line
SAN_FR_0021T "TT  FPI Station and Source" /vol/SAN145_22/SAN_FR_0021T-PPCR/TT  FPI Station and Source
SAN_FR_3131T DEFF_DEV /vol/SAN22_57/SAN_FR_3131T-PPAG/DEFF_DEV
SAN_FR_2241D BIX_E$    /vol/SAN99_45/SAN_FR_2241D-PPA/E
SAN_FR_2241D NULL_F$    /vol/SAN99_45/SAN_FR_2241D-PPA/F
SAN_FR_2241D TRIP   /vol/SAN99_45/SAN_FR_2241D-PPA/I
SAN_FR_2241D FINANCE   /vol/SAN99_45/SAN_FR_2241D-PPA/G

如您所见,第 2 列的行中有一个 space,但有一个双引号 (")。

尝试了 运行 这个命令,但它只适用于没有 spaces 的行。

command | awk '{print }'

输出:

"Threat
ZZ$    
"Control
"TT  
DEFF_DE
BIX_E$ 
NULL_F$
TRIP   
FINANCE

想要得到的是第 2 列的完整列表,即使上面有 space。

Threat for Security
ZZ$
Control Line
TT  FPI Station and Source
DEFF_DEV
BIX_E$
NULL_F$
TRIP
FINANCE

非常感谢任何帮助。

第一个解决方案: 使用您显示的示例,以及任何 awk,请尝试执行以下操作。简单的解释是,使用 match 函数匹配正则表达式 "[^"]*" 来匹配从第一次出现的 " 到下一次出现的 " 并打印匹配 sub-string 和 next 将跳过所有进一步的陈述。如果这种情况不成立,那么通常打印第二个字段的方式将起作用,因此打印 $2 然后。

awk 'match([=10=],/"[^"]*"/){print substr([=10=],RSTART+1,RLENGTH-2);next} {print }' Input_file


第二个解决方案: 使用 GNU awk,请尝试以下 awk 代码。

awk -v FPAT='[^ ]*|"[^"]+"' '{gsub(/^"|"$/,"",);print }' Input_file

使用 sed 您可以先查看不带引号的行,然后查看带引号的行。
那会给出丑陋的命令:

sed -r '/^[^"]*$/s/[^ ]* ([^ ]*).*//; s/[^"]*"([^"]*).*//' inputfile

这两部分可以合并,但在这次尝试中你需要删除最后的引号:

sed -r 's/[^ ]* (["][^"]*|[^ ]*).*//; s/"//' inputfile

这可以做得更聪明(没有修复 s/"// 删除 "

sed -r 's/[^ ]* ("([^"]*)|([^ ]*)).*//' inputfile

最后的解释sed

  • 's/[^ ]*
    删除第一个单词(所有没有 space 和下一个 space 的单词)。
  • ((...)|(...)).*//
    查找 2 个不同的匹配项 (OR),结果将以 </code> OR <code>.
    结尾 使用 </code> 将显示匹配的字符串。<br /> <code>.* 将删除该行的其余部分。
  • "([^"]*)
    " 开头的字段,但将引号保留在记住的字符串之外。
    该字符串将持续到下一个引号。
  • ([^ ]*)
    没有 spaces.
  • 的字符串