UNIX - 使用 SED 在 CSV 末尾添加带双引号的列

UNIX - 使用 SED 在 CSV 末尾添加带双引号的列

我有以下格式的数据:

"1";"abc"
"2";"dfg"
"3";"hij"

我使用以下命令添加一列:

sed "s/$/;"newc"/" file.csv

但我得到的最后一列没有引号:

"1";"abc";newc
"2";"dfg";newc
"3";"hij";newc

无法弄清楚如何更新它以添加双引号并获取:

"1";"abc";"newc"
"2";"dfg";"newc"
"3";"hij";"newc"

答案1

问题已解决在评论中没有适当的解释:

用单引号括住 sed 脚本不起作用?'s/$/;"newc"/'

是的,成功了!

这个答案将会阐明发生了什么以及解决方案为什么有效。


在您的原始命令中引用如下:

sed "s/$/;"newc"/" file.csv
#   ^     ^        a matching pair of quotes
#              ^ ^ another pair of quotes
#    s/$/;      /  these fragments are quoted
#          newc    this fragment is not quoted at all

您使用的引号会被 shell 占用。它们的存在会告诉 shell 对带引号的字符串和不带引号的字符串进行不同的处理,例如,带引号的分号 ( ;) 不是命令分隔符;然后它们会消失,即 shell 不会将它们传递给sed

注意newc不包含任何 shell 特有的字符,无论是否加引号,其行为都相同。这意味着newc不妨加引号,如下所示:

sed "s/$/;""newc""/" file.csv
#          ^    ^    added pair of quotes

但这相当于

sed "s/$/;newc/" file.csv

在 shell 使用了引号之后,sed会得到以下参数:s/$/;newc/file.csv。如您所见,该工具根本没有得到引号。

要将引号传递给sed您,您需要让它们“经受住”shell 的解析。有几种方法可以做到这一点。两种常见方法:

  1. 使用 . 进行转义\在双引号内,您可以转义双引号字符,因此它会被视为引号字符串的一部分,而不是结束引号。 在您的例子中:

    sed "s/$/;\"newc\"/" file.csv
    
  2. 混合引号。单引号内仍保留双引号。上述解决方案利用了这一事实:

    sed 's/$/;"newc"/' file.csv
    

    双引号内的单引号也保留。例如,如果您需要将文字'"参数传递给echo,则可以使用以下命令:

    echo "'"'"'
    #    ^ ^    # a pair of double quotes that make the single quote survive
    #       ^ ^ # a pair of single quotes that make the double quote survive
    

有时,最好set -x在“行为不当”的命令之前调用它,以了解 shell 解析它后剩下的内容。您的原始命令和两个修复后的命令生成此内容(sed为清晰起见,省略了输出):

$ sed "s/$/;"newc"/" file.csv       # original command
+ sed s/$/;newc/ file.csv
$ # the above line contains what sed really got
$ sed "s/$/;\"newc\"/" file.csv     # fixed
+ sed s/$/;"newc"/ file.csv
$ # this time sed got the right string
$ sed 's/$/;"newc"/' file.csv       # also fixed
+ sed s/$/;"newc"/ file.csv
$ # again the right string
$ 

注意:最后调用set +x以恢复set -x所做的操作。

相关内容