我有以下格式的数据:
"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 的解析。有几种方法可以做到这一点。两种常见方法:
使用 . 进行转义
\
在双引号内,您可以转义双引号字符,因此它会被视为引号字符串的一部分,而不是结束引号。 在您的例子中:sed "s/$/;\"newc\"/" file.csv
混合引号。单引号内仍保留双引号。上述解决方案利用了这一事实:
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
所做的操作。