我有一个这样的数据
"Apple grape","Banana"orange","Red green"
"Apple grape","Bananaorange","Red green"
我想删除使用或命令"
之间存在的单引号。Banana
orange
awk
sed
答案1
sed 's/\([^,]\)"\([^,]\)/\1\2/g' file
这将用相同的内容替换非逗号 ( [^,]
)、双引号和非逗号的所有非重叠序列,但不带双引号。
这无法处理模式在重叠子字符串处匹配的情况,例如...""...
and ..."."...
。我暂时不讨论这个问题,因为尚不清楚这些情况是否可能出现在用户数据中。运行替换两次将解决这些情况。
输出在终端上产生,因此如果要保存它,请重定向到文件。
答案2
假设您的字段中没有逗号或换行符,并且所有字段都像示例中那样用双引号引起来,那么您可以在每个 Unix 机器上的任何 shell 中使用任何 sed:
$ sed 's/"//g; s/,/","/g; s/.*/"&"/' file
"Apple grape","Bananaorange","Red green"
答案3
我们所追求的双引号的两边总是有邻居。邻居永远都是非逗号。但由于 sed 不进行环视,因此正则表达式将消耗输入。因此我们必须循环。
sed -Ee '
:loop
s/([^,])"([^,])/\1\2/
tloop
' file
Perl 的环视使其变得简洁。
perl -lpe 's/(?<=[^,])"(?=[^,])//g' file
或者,我们转换用于形成字段分隔符的双引号。然后,哪些引言脱颖而出,哪些引言就应该被删除。然后我们进行逆变换。
sed -Ee '
s/^"|","|"$/\n/g
s/"//g
s/^\n|\n$/"/g
s/\n/","/g
' file
注意:使用带有扩展正则表达式 -E 的 GNU sed。
答案4
Whith GNUawk
使用gensub()
函数:
awk '{print gensub(/([[:alpha:]]+)"([[:alpha:]]+)/,"\\1\\2","g")}' file
"Apple grape","Bananaorange","Red green"
"Apple grape","Bananaorange","Red green"