我需要在bash脚本中将所有两个“,”之间的“,”替换为“;”。我已经很接近了,但是互联网和stackoverflow上的大量时间让我想到了这一点:
echo ',,Lung,,"Lobular, each.|lungs, right.",false,,,,"organ, left.",,,,,' | sed -r ':a;s/(".*?),(.*?")/\1;\2/;ta'
结果:
,,Lung,,"Lobular; each.|lungs; right.";false;;;;"organ; left.",,,,,
正确的是:
,,Lung,,"Lobular; each.|lungs; right.",false,,,,"organ; left.",,,,,
答案 0 :(得分:2)
不确定如何处理双引号奇数的行(例如,双引号的字符串跨越多行),但是也许:
awk '!(NR%2){gsub(",",";")} 1' RS=\" ORS=\"
这只是将"
视为记录分隔符,并且仅对奇数记录进行替换。似乎可以按需工作。 (或者相反,它可以按您期望的方式工作!)
正如oguz在评论中指出的那样,这在末尾额外打印了"
。可以通过以下方式解决此问题:
awk '!(NR%2){gsub(",",";")} {printf RFS $0} {RFS="\""}' RS=\"
这有点难看,但更正确。 (或者更确切地说,是不太正确!)如果您的输入流以"
结尾,则该引用将被截断。但是,如果您的输入以换行符而不是"
终止,则将按照您的意愿进行操作。
OTOH,您可能只想做:
perl -wpE 'BEGIN{$/=\1}; y/,/;/ if $in; $in = ! $in if $_ eq "\""'
读取一个字符并使用一个简单的状态机。 ($_
是当前字符,因此$in = ! $in
会在看到双引号时更改状态,并且音译仅在$in
非零时发生。)
答案 1 :(得分:1)
如果您/ really /想使用sed
,则可以进行整行替换,并在现有表达式的开头加入类似^(([^"]*"[^"*]")*[^"]*)
的子句,以确保匹配的引号是“奇数”。