为什么 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'