为什么 xargs 从输入中去除引号?

为什么 xargs 从输入中去除引号?

为什么 xargs 从输入文本中去除引号?

这是一个简化的示例:

echo "/Place/='http://www.google.com'" | xargs echo

输出

/Place/=http://www.google.com

有什么办法可以解决这个问题吗? (xargs -0 对我没有帮助)

答案1

如果你xargs忽略引号好的灵魂之一是使用xargs标志xargs -0

直接来自手册页选项

选项-0,--null

输入项以空字符而不是空格终止,并且引号和反斜杠并不特殊(每个字符均按字面意思理解)。禁用文件结尾字符串,该字符串的处理方式与任何其他参数一样。当输入项可能包含空格、引号或反斜杠时很有用。 GNU find -print0 选项生成适合此模式的输入。

我检查过一个 GNU 系统,该系统使用-d选项(而不仅仅是)将分隔符设置为特定值(如换行符-0)也会导致xargs不特殊对待引号等:

-bash-4.3$ { echo "a'b'c"; echo d; } | xargs -d$'\n' echo
a'b'c d
-bash-4.3$ rpm -qf "$(which xargs)"
findutils-4.6.0.0.99.11a05-alt1.x86_64
-bash-4.3$ { echo "a'b'c"; echo d; } | xargs echo
abc d
-bash-4.3$ 

答案2

对于GNU xargs,我在联机帮助页中找到了另一个解决方案:显式指定分隔符为“\n”。这将关闭对报价的特殊处理:

--delimiter=delim, -d delim

输入项以指定字符结束。指定的分隔符可以是单个字符、C 样式字符转义符(例如 \n)或者八进制或十六进制转义码。八进制和十六进制转义码被理解为 printf 命令。不支持多字节字符。处理输入时,引号和反斜杠并不特殊;输入中的每个字符均按字面意思处理。

所以,

echo "/Place/='http://www.google.com'" | xargs -d'\n' echo

输出

/Place/='http://www.google.com'

答案3

xargs手册中:

如果您希望输入参数包含空格或水平制表符,请将其用双引号或撇号括起来。如果参数包含双引号字符 ( "),则必须将参数括在撇号内。相反,如果参数包含撇号 ( '),则必须将参数用双引号引起来。您还可以\在字符前面放置反斜杠 ( ),以告诉 xargs 忽略该字符可能具有的任何特殊含义(例如,空格字符或引号)。

这意味着如果引号本身被引用,您可以转义引号:

$ echo "/Place/=\'http://www.google.com\'" | xargs echo
/Place/='http://www.google.com'

会起作用,但echo /Place/=\'http://www.google.com\' | xargs echo不会。

答案4

我在这里找到了另一个解决方案https://stackoverflow.com/a/17468560/1795821这建议使用sed转义引号。

例如:

sh-3.2$ echo "/Place/='http://www.google.com'" | sed "s/\'/\\\'/g" | xargs echo
/Place/='http://www.google.com'

相关内容