¿Por qué xargs elimina las comillas de la entrada?

25

¿Por qué xargs elimina las comillas del texto de entrada?

Aquí hay un ejemplo simplificado:

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

salidas

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

¿Hay alguna forma de solucionar esto? (Xargs -0 no me ayuda)

ddario
fuente
1
xargstrata las comillas y las barras invertidas especialmente como parte de la especificación . Publica lo que estás intentando hacer en su xargslugar.
jw013
3
xargs -0funciona para mí aquí ... ¿Por qué no te ayuda?
derobert

Respuestas:

10

Del xargsmanual:

Si desea que un argumento de entrada contenga espacios en blanco o pestañas horizontales, escríbalo entre comillas dobles o apóstrofes. Si el argumento contiene un carácter de comillas dobles ( "), debe encerrar el argumento en apóstrofes. Por el contrario, si el argumento contiene un apóstrofe ( '), debe encerrar el argumento entre comillas dobles. También puede colocar una barra diagonal inversa ( \) delante de un carácter para indicarle a xargs que ignore cualquier significado especial que pueda tener el carácter (por ejemplo, espacios en blanco o comillas).

Esto significa que puede escapar de las comillas si las comillas se citan a sí mismas:

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

funcionará pero echo /Place/=\'http://www.google.com\' | xargs echono lo hará.

Matteo
fuente
1
Nada en contra de los votos negativos, pero un comentario sobre el motivo ayudaría :-)
Matteo
3
¿Qué pasa si está entrando tuberías? Si tengo un script que sale "/Place/='http://www.google.com'", ¿cómo puedo escapar de él correctamente?
Roger Filmyer
1
@RogerFilmyer your_script | paralelo --shellquote | ...
Ole Tange
19

si quieres xargsa ignorar las cotizaciones uno de los buenos soultion puede ser el uso de xargsla bandera xargs -0

Directamente desde la página Man OPCIONES

OPCIONES -0, --nulo

Los elementos de entrada terminan con un carácter nulo en lugar de un espacio en blanco, y las comillas y la barra diagonal inversa no son especiales (cada carácter se toma literalmente). Inhabilita el final de la cadena del archivo, que se trata como cualquier otro argumento. Útil cuando los elementos de entrada pueden contener espacios en blanco, comillas o barras diagonales inversas. La opción GNU find -print0 produce una entrada adecuada para este modo.

He comprobado en un sistema GNU que establecer el delimitador en un valor específico (como una nueva línea) con la -dopción (y no solo -0) también haría que xargsno se trataran las comillas, etc. especialmente:

-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$ 
Balman Rawat
fuente
7

Encontré otra solución en la página de manual: especifique explícitamente que el delimitador sea '\ n'. Esto desactiva el manejo especial de las cotizaciones:

--delimiter = delim, -d delim

Los elementos de entrada terminan con el carácter especificado. El delimitador especificado puede ser un solo carácter, un escape de caracteres de estilo C como \ n, o un código de escape octal o hexadecimal. Los códigos de escape octal y hexadecimal se entienden como para el comando printf. Los caracteres multibyte no son compatibles. Al procesar la entrada, las comillas y la barra diagonal inversa no son especiales; Todos los caracteres de la entrada se toman literalmente.

Asi que,

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

salidas

/Place/='http://www.google.com'
fungusakafungus
fuente
Tenga en cuenta que implica GNU xargso compatible
Stéphane Chazelas
También tenga en cuenta que también evita que el espacio y la pestaña se reconozcan como delimitadores (probablemente también en el caso del OP).
Stéphane Chazelas
Balman dio una solución similar (bueno, en realidad @imz ), aunque la suya es algo mejor porque evita el uso del ksh93 $'...'operador de citas que no se encuentra en todas las implementaciones de shell.
Stéphane Chazelas
4

Encontré otra solución aquí /programming//a/17468560/1795821 que sugiere usar sedpara escapar de las comillas.

Por ejemplo:

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