Pourquoi xargs supprime-t-il les citations de l'entrée?

25

Pourquoi xargs supprime-t-il les citations du texte saisi?

Voici un exemple simplifié:

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

les sorties

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

Y a-t-il un moyen de contourner cela? (xargs -0 ne m'aide pas)

ddario
la source
1
xargstraite les guillemets et les contre-obliques spécialement dans le cadre de la spécification . Affichez xargsplutôt ce que vous essayez de faire .
jw013
3
xargs -0travaille pour moi ici ... Pourquoi ça ne vous aide pas?
derobert

Réponses:

10

Du xargsmanuel:

Si vous souhaitez qu'un argument d'entrée contienne des blancs ou des tabulations horizontales, placez-le entre guillemets doubles ou apostrophes. Si l'argument contient un double guillemet ( "), vous devez placer l'argument entre apostrophes. Inversement, si l'argument contient une apostrophe ( '), vous devez placer l'argument entre guillemets doubles. Vous pouvez également placer une barre oblique inverse ( \) devant un caractère pour indiquer à xargs d'ignorer toute signification spéciale que le personnage peut avoir (par exemple, des espaces blancs ou des guillemets).

Cela signifie que vous pouvez échapper les guillemets si les guillemets sont eux-mêmes cités:

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

fonctionnera mais echo /Place/=\'http://www.google.com\' | xargs echone fonctionnera pas.

Matteo
la source
1
Rien contre les votes bas mais un commentaire sur la raison aiderait :-)
Matteo
3
Et si vous canalisez en entrée? Si j'ai un script qui sort "/Place/='http://www.google.com'", comment puis-je l'échapper correctement?
Roger Filmyer
1
@RogerFilmyer your_script | parallèle --shellquote | ...
Ole Tange
19

si vous voulez xargsde ne pas tenir compte des citations un des bons soultion peut être l'utilisation du xargsdrapeau xargs -0

Directement depuis la page de manuel OPTIONS

OPTIONS -0, --null

Les éléments d'entrée se terminent par un caractère nul au lieu de par des espaces, et les guillemets et les barres obliques inverses ne sont pas spéciaux (chaque caractère est pris littéralement). Désactive la fin de la chaîne de fichiers, qui est traitée comme tout autre argument. Utile lorsque les éléments d'entrée peuvent contenir des espaces blancs, des guillemets ou des barres obliques inverses. L'option GNU find -print0 produit une entrée adaptée à ce mode.

J'ai vérifié sur un système GNU que la définition du délimiteur à une valeur spécifique (comme une nouvelle ligne) avec -doption (et pas seulement -0) empêcherait également xargsde traiter les guillemets, etc. spécialement:

-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
la source
7

J'ai trouvé une autre solution dans la page de manuel: spécifiez explicitement que le délimiteur est '\ n'. Cela désactive la gestion spéciale des devis:

--delimiter = delim, -d delim

Les éléments d'entrée se terminent par le caractère spécifié. Le délimiteur spécifié peut être un seul caractère, un caractère d'échappement de style C tel que \ n, ou un code d'échappement octal ou hexadécimal. Les codes d'échappement octaux et hexadécimaux sont compris comme pour la commande printf. Les caractères multi-octets ne sont pas pris en charge. Lors du traitement de l'entrée, les guillemets et les barres obliques inverses ne sont pas spéciaux; chaque caractère de l'entrée est pris littéralement.

Alors,

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

les sorties

/Place/='http://www.google.com'
fungusakafungus
la source
Notez qu'il implique GNU xargsou compatible
Stéphane Chazelas
Notez également que cela empêche également l'espace et la tabulation d'être reconnus comme délimiteurs (probablement aussi bien dans le cas de l'OP).
Stéphane Chazelas
Balman a donné une solution similaire (bien en fait @imz ) bien que la vôtre soit un peu meilleure en ce qu'elle évite l'utilisation de l' ksh93 $'...'opérateur de citation qui ne se trouve pas dans chaque implémentation du shell.
Stéphane Chazelas
4

J'ai trouvé une autre solution ici /programming//a/17468560/1795821 qui suggère d'utiliser sedpour échapper aux citations.

Par exemple:

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