Question

Je veux trouver une commande bash qui me permettra de grep tous les fichiers dans un répertoire et é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 doubles. Si je supprime les guillemets, cependant, la commande redirige la sortie de l'ensemble de la commande d'un seul fichier appelé « {} ». Out au lieu de une série de fichiers individuels.

Quelqu'un sait-il d'une façon de le faire en utilisant xargs? Je viens d'utiliser ce scénario grep comme exemple pour illustrer mon problème avec xargs donc des solutions qui n'utilisent pas xargs ne sont pas aussi applicables pour moi.

Était-ce utile?

La solution

Ne faites pas l'erreur de faire ceci:

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

Ceci brisera sous beaucoup de conditions, y compris les noms de fichiers funky et il est impossible de citer à droite. Votre doit toujours être {} un seul argument complètement séparé à la commande pour éviter les bugs d'injection de code. Ce que vous devez faire, est la suivante:

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

applique à xargs ainsi que find.

Par ailleurs, ne jamais utiliser xargs sans l'option -0 (sauf pour un temps très rare et contrôlé utilisation interactive où vous n'êtes pas inquiet pour détruire vos données).

Aussi, ne pas analyser ls. Déjà. Utilisez les jokers ou au lieu <=>: http://mywiki.wooledge.org/ParsingLs

Utilisez pour tout ce qui <=> a besoin récursion et une boucle simple avec un glob pour tout le reste:

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

ou non récursif:

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

Remarquez l'utilisation correcte des guillemets.

Autres conseils

Une solution sans xargs est la suivante:

find . -mindepth 1 -maxdepth 1 -type f -exec sh -c "grep ABC '{}' > '{}.out'" \;

... et la même chose peut être fait avec <=>, il se trouve:

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

Modifier : guillemets simples ajoutés après la remarque de lhunath .

Je suppose que votre exemple est juste un exemple et que vous pourriez avoir besoin> pour d'autres choses. http://www.gnu.org/software/parallel/ peut-être votre secours . Il n'a pas besoin de citer tant à mesure que vos noms de fichiers ne contiennent pas \ n:

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

Si vous avez des noms de fichiers avec \ n en elle:

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

En prime vous obtenez les travaux sont exécutés en parallèle.

Modifier.

Vous pouvez installer GNU Parallel simplement par:

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

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

10 secondes d'installation:

wget pi.dk/3 -qO - | sh -x
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top