Regex sed:替换增量记录中引用字段中的双引号

Regex sed:替换增量记录中引用字段中的双引号,regex,unix,sed,Regex,Unix,Sed,给定一个带有以下记录的可选带引号的管道分隔文件: “foo”|“bar”| 123 |“9”钉子|“2” “等等”,“等等”456“枪”和“玫瑰” “brik”|“brak”| 789 |“BB”King”|“0” “阴”“阳”“约翰”“美洲狮”“梅伦坎普”“5” 我想替换任何不在分隔符旁边的双引号 我使用了下面的方法,它几乎可以工作。只有一个例外 sed“s/\([^ |]\)\”\([^ |]\)/\1'\2/g”a.txt 输出如下所示: “foo”|“bar”| 123 |“9’钉”|“

给定一个带有以下记录的可选带引号的管道分隔文件:

“foo”|“bar”| 123 |“9”钉子|“2”
“等等”,“等等”456“枪”和“玫瑰”
“brik”|“brak”| 789 |“BB”King”|“0”
“阴”“阳”“约翰”“美洲狮”“梅伦坎普”“5”

我想替换任何不在分隔符旁边的双引号

我使用了下面的方法,它几乎可以工作。只有一个例外

sed“s/\([^ |]\)\”\([^ |]\)/\1'\2/g”a.txt

输出如下所示:

“foo”|“bar”| 123 |“9’钉”|“2”
“等等”|“等等”| 456 |“枪和玫瑰”|“7”
“brik”|“brak”| 789 |“'BB'King”|“0”
“阴”|“阳”| 789 |“约翰·美洲豹·梅伦坎普”|“5”

如果第二组引号是用一个字符分隔的,就像“N”玫瑰一样,它不会捕捉到第二组引号。有人知道为什么会这样以及如何修复它吗?同时,我只是将输出传输到第二个正则表达式以处理特殊情况。我更喜欢一次完成,因为有些文件可能会更大


提前感谢。

您可以在
sed
中使用替换两次:

sed -r "s/([^|])\"([^|])/\1'\2/g; s/([^|])\"([^|])/\1'\2/g" file
"foo"|"bar"|123|"9' Nails"|"2"
"blah"|"blah"|456|"Guns 'N' Roses"|"7"
"brik"|"brak"|789|"'BB' King"|"0"
"yin"|"yang"|789|"John 'Cougar' Mellencamp"|"5"
sed实现了一种“while”循环:

如果先前的
s//
命令替换了某个内容,则
t
命令将循环到标签
a
。因此,将重复替换,直到找不到其他匹配项为止

此外,由于采用了零宽度前瞻,perl可以在不循环的情况下处理您的案例:

perl -pe 's/[^|]\K"(?!\||$)/'\''/g'
但它不处理连续的双引号,因此循环:

perl -pe 's//'\''/g while /[^|]\K"(?!\||$)/' file

您可能喜欢使用
\x27
而不是笨拙的
'\''
方法在单引号字符串中插入单引号。与perl和GNU-sed一起使用。

我不得不跳出parens,但结果是这样。我从未想过要运行相同的模式两次。我将把它添加到我的技巧包中。谢谢!@RikBitter,您使用了sed-r?您应该使用正确的CSV和正确的CSV解析器:字段中嵌入的双引号加倍:
“blah”|“blah”|“456”|“Guns”“N”“Roses”|“7”
同意。不幸的是,我无法控制源文件的生成。我必须按原样处理它。顺便说一句,感谢perl解决方案。
perl -pe 's//'\''/g while /[^|]\K"(?!\||$)/' file