web-dev-qa-db-fra.com

Comment utiliser les espaces dans les noms de fichiers lors de l'utilisation de Xargs sur trouver des résultats?

Une de mes pratiques communes consiste à effectuer des greps sur tous les fichiers d'un certain type, par exemple, trouver tous les fichiers HTML qui ont le mot "Rumpus" en eux. Pour le faire, j'utilise

find /path/to -name "*.html" | xargs grep -l "rumpus"

De temps en temps, find retournera un fichier avec un espace dans son nom tel que my new file.html. Lorsque xargs a transmis cela à grep, cependant, je reçois ces erreurs:

grep: /path/to/bad/file/my: No such file or directory
grep: new: No such file or directory
grep: file.html: No such file or directory

Je peux voir ce qui se passe ici: le tuyau ou le xargs traite les espaces sous forme de délimiteurs entre fichiers. Pour la vie de moi, je ne peux pas comprendre comment prévenir ce comportement. Peut-il être fait avec find + xargs? Ou dois-je utiliser une commande entièrement différente?

29
abeger

Utilisation

find ... -print0 | xargs -0 ...

par exemple.

find /path/to -name "*.html"  -print0 | xargs -0  grep -l "rumpus"

de la page Trouver man

-print0
          True; print the full file name on the standard  output,  followed
          by  a  null  character  (instead  of  the  newline character that
          ‘-print’ uses).  This allows file names that contain newlines  or
          other  types  of  white space to be correctly interpreted by pro-
          grams that process the find output.  This option  corresponds  to
          the ‘-0’ option of xargs.
29
user9517

Vous n'avez pas besoin d'utiliser xargs, car -trouver peut exécuter des commandes elles-mêmes. Ce faisant cela, vous n'avez pas à vous soucier de la coque d'interpréter les caractères dans le nom.

find /path/to -name "*.html" -exec grep -l "rumpus" '{}' +

de la page Trouver man

-exec commande {} +
[.____] Cette variante de l'action -exec exécute la commande spécifiée sur les fichiers sélectionnés, mais la ligne de commande est construite en ajoutant chaque nom de fichier sélectionné à la fin; Le nombre total d'invocations de la commande sera beaucoup moins que le nombre de fichiers correspondants. La ligne de commande est intégrée de la même manière que Xargs construit ses lignes de commande. Seule une instance de {{} 'est autorisée dans la commande. La commande est exécutée dans le répertoire de départ.

16
sciurus

Si la recherche et les versions XARG sur votre système ne supportent pas -print0 et -0 Commutateurs (par exemple AIX Rechercher et Xargs) Vous pouvez utiliser ceci:

find /your/path -name "*.html" | sed 's/ /\\ /g' | xargs grep -l "rumpus"

Ici, sed veillera à échapper aux espaces pour Xargs.

8
Jan Ptáčník