sed:替换分隔记录中引用字段中的双引号
sed: Replacing a double quote in a quoted field within a delmited record
给定一个可选引用的管道分隔文件,其中包含以下记录:
"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 "s/\([^|]\)\"\([^|]\)/'/g" a.txt
输出如下所示:
"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"
如果第二组引号像 Guns "N" Roses 中那样由单个字符分隔,则它不会捕获第二组引号。有谁知道这是为什么以及如何解决?与此同时,我只是将输出通过管道传输到第二个正则表达式来处理特殊情况。我宁愿一次完成此操作,因为某些文件可能很大。
提前致谢。
您可以在 sed
中使用两次替换:
sed -r "s/([^|])\"([^|])/'/g; s/([^|])\"([^|])/'/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" 循环:
sed ':a; s/\([^|]\)"\([^|]\)/'\''/g; ta' file
如果之前的 s///
命令替换了某些内容,t
命令将循环到标签 a
。这样会重复替换,直到找不到其他匹配项。
此外,perl 无需循环即可处理您的情况,这要归功于零宽度先行:
perl -pe 's/[^|]\K"(?!\||$)/'\''/g'
但是它不处理连续的双引号,所以循环:
perl -pe 's//'\''/g while /[^|]\K"(?!\||$)/' file
您可能喜欢使用 \x27
而不是笨拙的 '\''
方法在单引号字符串中插入单引号。适用于 perl 和 GNU sed。
给定一个可选引用的管道分隔文件,其中包含以下记录:
"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 "s/\([^|]\)\"\([^|]\)/'/g" a.txt
输出如下所示:
"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"
如果第二组引号像 Guns "N" Roses 中那样由单个字符分隔,则它不会捕获第二组引号。有谁知道这是为什么以及如何解决?与此同时,我只是将输出通过管道传输到第二个正则表达式来处理特殊情况。我宁愿一次完成此操作,因为某些文件可能很大。
提前致谢。
您可以在 sed
中使用两次替换:
sed -r "s/([^|])\"([^|])/'/g; s/([^|])\"([^|])/'/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" 循环:
sed ':a; s/\([^|]\)"\([^|]\)/'\''/g; ta' file
如果之前的 s///
命令替换了某些内容,t
命令将循环到标签 a
。这样会重复替换,直到找不到其他匹配项。
此外,perl 无需循环即可处理您的情况,这要归功于零宽度先行:
perl -pe 's/[^|]\K"(?!\||$)/'\''/g'
但是它不处理连续的双引号,所以循环:
perl -pe 's//'\''/g while /[^|]\K"(?!\||$)/' file
您可能喜欢使用 \x27
而不是笨拙的 '\''
方法在单引号字符串中插入单引号。适用于 perl 和 GNU sed。