替换bash脚本中两个引号之间的所有逗号

时间:2019-05-21 17:58:00

标签: regex bash sh quotes comma

我需要在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.",,,,,

2 个答案:

答案 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,则可以进行整行替换,并在现有表达式的开头加入类似^(([^"]*"[^"*]")*[^"]*)的子句,以确保匹配的引号是“奇数”。