仅替换第 N 列中的所有双引号

Posted

技术标签:

【中文标题】仅替换第 N 列中的所有双引号【英文标题】:Replace all double quotes only in Nth Column 【发布时间】:2021-10-03 10:02:58 【问题描述】:

我有一个这样的文件

abc|def||ghi|jklm||uv||xyz
abc|def||ghi|jklm|nopqrst|uv||xyz
abc|def||ghi|jklm|nopq"rst|uv||xyz
abc|def||ghi|jklm|"nopqrst"|uv||xyz
abc|def||ghi|jklm|"nopq"rst"|uv||xyz
abc|def||ghi|jklm|"nopq"r"st"|uv||xyz

第 6 列可以双引号。我想用反斜杠双引号 (\") 替换此字段中所有出现的双引号

我希望我的输出看起来像

abc|def||ghi|jklm||uv||xyz
abc|def||ghi|jklm|nopqrst|uv||xyz
abc|def||ghi|jklm|nopq\"rst|uv||xyz
abc|def||ghi|jklm|"nopqrst"|uv||xyz
abc|def||ghi|jklm|"nopq\"rst"|uv||xyz
abc|def||ghi|jklm|"nopq\"r\"st"|uv||xyz

我尝试了以下的组合,但每次都结束

sed -i 's/\"/\\\"/2' file.txt (this replaces only 2nd occurrence)
sed -i 's/\"/\\\"/2g' file.txt (this replaces only 2nd occurrence and all rest also)

我的文件将有数百万行;所以我可能只需要一个 sed 或 awk 命令。 请帮忙。

【问题讨论】:

第 6 列可以有"abcxyz" 这样的数据吗?也就是说,只有开始或结束引号存在。 你能不能在第 6 列有|s,例如"foo|bar"?你可以在任何其他列中引用吗? 【参考方案1】:

您可以在awk 的任何版本中使用此awk 解决方案:

awk 'BEGIN FS=OFS="|" 
   c1 = substr($6, 1, 1)
   c2 = substr($6, length($6), 1)
   s = substr($6, 2, length($6)-2)
   gsub(/"/, "\\\"", s)
   $6 = c1 s c2
 1' file

abc|def||ghi|jklm||uv||xyz
abc|def||ghi|jklm|nopqrst|uv||xyz
abc|def||ghi|jklm|nopq\"rst|uv||xyz
abc|def||ghi|jklm|"nopqrst"|uv||xyz
abc|def||ghi|jklm|"nopq\"rst"|uv||xyz
abc|def||ghi|jklm|"nopq\"r\"st"|uv||xyz

【讨论】:

谢谢阿努巴瓦。这非常适合我的要求。【参考方案2】:

这可能对你有用(GNU sed):

sed -E 's/[^|]*/\n&\n/6            # isolate the 6th field
        h                          # make a copy
        s/"/\\"/g                  # replace " by \"
        s/\\(")\n|\n\\(")/\1\n\2/g # repair start and end "s
        H                          # append amended line to copy
        g                          # get copies to current line
        s/\n.*\n(.*)\n.*\n(.*)\n.*/\2\1/' file # swap fields

将第 6 个字段用换行符括起来,并在保留空间中复制。

如果字段以" 开头和结尾,则将所有" 替换为\" 并删除字段开头和结尾的\

将修改后的行附加到副本中,并用双行替换当前行。

使用模式匹配将复制的第 6 行字段替换为修改后的字段。

【讨论】:

【参考方案3】:

如果这不是您需要的全部,请编辑您的问题以提供更具代表性的示例输入/输出,包括不适用的情况:

$ sed 's/"/\\"/g; s/|\\"/|"/g; s/\\"|/"|/g' file
abc|def||ghi|jklm||uv||xyz
abc|def||ghi|jklm|nopqrst|uv||xyz
abc|def||ghi|jklm|nopq\"rst|uv||xyz
abc|def||ghi|jklm|"nopqrst"|uv||xyz
abc|def||ghi|jklm|"nopq\"rst"|uv||xyz
abc|def||ghi|jklm|"nopq\"r\"st"|uv||xyz

以上内容适用于任何 sed。

【讨论】:

谢谢埃德莫顿。您的解决方案更通用,不仅限于第 6 列。这肯定对我以后的工作很有用。再次感谢。

以上是关于仅替换第 N 列中的所有双引号的主要内容,如果未能解决你的问题,请参考以下文章

用双引号替换单引号并排除某些元素

文档中如何批量替换所有的英文双引号为中文双引号,同时保证引号中的文字内容不变?

将双引号添加到列中的值,只要值在数据框中有引号

用BIML脚本中的csv文件替换所有双引号

js怎么在引号里写函数

用单引号替换双引号以存储在 SQLite 中