198 votes

Comment utiliser > dans une commande xargs ?

Je veux trouver une commande bash qui me permettra de grep tous les fichiers d'un répertoire et d'écrire la sortie de cette grep dans un fichier séparé. Je pense aurait été de faire quelque chose comme ceci

ls -1 | xargs -I{} "grep ABC '{}' > '{}'.out"

mais, autant que je sache, xargs n'aime pas les guillemets. Si je supprime les guillemets, cependant, la commande redirige la sortie de la commande vers un fichier unique appelé '{}'.au lieu d'une série de fichiers individuels.

Personne ne sait d'une façon de faire cela en utilisant xargs? J'ai juste utilisé ce grep scénario comme un exemple pour illustrer mon problème avec xargs donc toutes les solutions qui ne l'utilisez pas xargs ne sont pas applicables pour moi.

240voto

lhunath Points 27045

Ne faites pas l'erreur de le faire:

sh -c "grep ABC {} > {}.out"

Cela permettra de briser dans beaucoup de conditions, y compris funky noms de fichiers et il est impossible de citer tout. Ce que vous devez faire, c'est ceci:

sh -c 'grep ABC "$1" > "$1.out"' -- {}

S'applique à l' xargs ainsi que find.

Par le chemin, ne jamais utiliser de xargs sans l' -0 option (sauf pour de très rares et contrôlés, et un temps d'utilisation interactive où vous n'êtes pas inquiet au sujet de la destruction de vos données).

Aussi, ne pas analyser ls. Jamais. L'utilisation d'expansion ou d' find à la place: http://mywiki.wooledge.org/ParsingLs

Utiliser find pour tout ce qui a besoin de la récursivité et d'une simple boucle avec un glob pour tout le reste:

find /foo -exec sh -c 'grep "$1" > "$1.out"' -- {} \;

ou non-récursive:

for file in *; do grep "$file" > "$file.out"; done

Avis de la bonne utilisation des guillemets.

52voto

Stephan202 Points 27707

Une solution sans `` est la suivante :

.. .et la même chose peut être fait avec`` , il s’avère que :


Edit: ajoutés après la remarque de lhunathde guillemets simples.

16voto

Ole Tange Points 4907

Je suppose que votre exemple est juste un exemple et que vous pouvez avoir besoin d' > pour d'autres choses. GNU Parallèle http://www.gnu.org/software/parallel/ peut-être que votre secours. Il n'a pas besoin supplémentaire en citant aussi longtemps que vos noms de fichiers ne contiennent pas de \n:

ls | parallel "grep ABC {} > {}.out"

Si vous avez les noms de fichiers avec \n:

find . -print0 | parallel -0 "grep ABC {} > {}.out"

Comme un bonus supplémentaire, vous obtenez les travaux s'exécutent en parallèle.

Edit.

Vous pouvez installer GNU Parallèle simplement par:

wget http://git.savannah.gnu.org/cgit/parallel.git/plain/src/parallel
chmod 755 parallel

Regarder les vidéos d'intro pour en savoir plus: http://pi.dk/1

10 secondes d'installation:

wget pi.dk/3 -qO - | sh -x

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X