Je veux exécuter une commande java une fois pour chaque match de ls | grep pattern -
. Dans ce cas, je pense que je pourrais le faire, find pattern -exec java MyProg '{}' \;
mais je suis curieux à propos du cas général. Existe-t-il un moyen facile de dire "exécuter une commande une fois pour chaque ligne d'entrée standard"? (En poisson ou bash.)
162
printf "foo bar\nbaz bat" | xargs echo whee
va céderwhee foo bar baz bat
. Peut-être ajouter les options-L
ou-n
?La réponse acceptée a la bonne idée, mais la clé est de passer
xargs
le-n1
commutateur, ce qui signifie "Exécuter la commande une fois par ligne de sortie:"Ou, pour un seul fichier d'entrée, vous pouvez éviter le tuyau de
cat
tout et aller simplement avec:la source
xargs
à ne pas fonctionner sistdin
est vide:--no-run-if-empty
-r
: Si l'entrée standard ne contient pas de Non vides, ne pas courir la commande. Normalement, la commande est exécutée une fois, même s'il n'y a pas d'entrée. Cette option est une extension GNU.command
?Dans Bash ou tout autre shell de style Bourne (ash, ksh, zsh,…):
read -r
lit une seule ligne à partir de l'entrée standard (read
sans-r
interpréter les barres obliques inverses, vous ne voulez pas cela). Ainsi, vous pouvez effectuer l'une des opérations suivantes:la source
tail -f syslog | grep -e something -e somethingelse| while read line; do echo $line; done
ça n'a pas marché. Cela fonctionnait avec un fichier inséré dans lawhile
boucle, uniquementtail -f
avecgrep
, mais avec, mais pas avec les deux tuyaux. Donner lagrep
la--line-buffered
possibilité fait le travailcommand | while read -r line; do echo "$line" | command ; done
Je suis d'accord avec Keith, xargs est l'outil le plus général du travail.
J'utilise généralement une approche en 3 étapes.
Il existe des moyens plus petits et plus rapides, mais ces moyens fonctionnent presque toujours.
Un exemple simple:
les 2 premières lignes sélectionnent certains fichiers avec lesquels travailler, puis awk prépare une belle chaîne avec une commande à exécuter et quelques arguments, et $ 1 est la première colonne entrée dans le tube. Et enfin, je m'assure que xargs envoie cette chaîne à bash qui vient de l'exécuter.
C'est un peu exagéré, mais cette recette m'a aidé dans beaucoup d'endroits, car elle est très flexible.
la source
xargs -0
l’octet nul sert de séparateur d’enregistrement. Votre déclaration empreinte awk devrait donc êtreprintf("MyJavaProg --args \"%s\"\0",$1)
awk
vous pouvez le faire correspondre au modèle et ignorergrep
, par exemple,ls | awk '/xls/ {print...
GNU Parallel est conçu pour ce type de tâches. L'utilisation la plus simple est:
Regardez la vidéo d'introduction pour en savoir plus: http://www.youtube.com/watch?v=OpaiGYxkSuQ
la source
cat
ici puisqu'ongrep
peut directement lire le fichier< stuff grep pattern
mais estgrep pattern stuff
sans redirection ni cat requise du tout. Néanmoins, cela ne change pas matériellement votre argument et si vous pensez qu'il est plus clair de toujours utiliser les éléments d'un tuyau qui commence parcat
, puis vous donner le pouvoirEn outre,
while read
boucle dans la coquille de poisson (je suppose que vous voulez coquille de poisson, compte tenu que vous avez utilisé une étiquette de poisson ).Peu de points à noter.
read
ne prend pas-r
argument, et il n'interprète pas vos barres obliques inverses, afin de rendre l'utilisation la plus courante possible.$line
, car contrairement à bash, le poisson ne sépare pas les variables par des espaces.command
par lui-même est une erreur de syntaxe (pour attraper une telle utilisation d'arguments fictifs). Remplacez-le par la commande réelle.la source
while
besoin d'être jumelé avecdo
&done
au lieu deend
?Si vous devez contrôler exactement où l'argument d'entrée est inséré dans votre ligne de commande ou si vous devez le répéter plusieurs fois, utilisez-le
EXEMPLE 1xargs -I{}
.Créez une structure de dossier vide
Exemple n ° 2another_folder
qui reflète les sous-dossiers du répertoire actuel:Appliquez une opération sur une liste de fichiers provenant de stdin, dans ce cas, effectuez une copie de chaque
.html
fichier en ajoutant une.bak
extension:De la
xargs
page de manuel MacOS / BSD :xargs
Page de manuel Linux :la source
Lorsque je traite des entrées potentiellement non normalisées, j'aime voir le travail entier «épelé» ligne par ligne pour l'inspection visuelle avant de l'exécuter (en particulier lorsqu'il s'agit de quelque chose de destructeur comme le nettoyage de la boîte aux lettres des personnes).
Donc, ce que je fais est de générer une liste de paramètres (c'est-à-dire des noms d'utilisateurs), de le nourrir dans un fichier à la manière d'un enregistrement par ligne, comme ceci:
Ensuite, j'ouvre la liste
vim
et la sélectionne avec des expressions de recherche et de remplacement jusqu'à obtenir une liste des commandes complètes devant être exécutées, comme ceci:Ainsi, si votre expression rationnelle est incomplète, vous verrez dans quelle commande auront des problèmes potentiels (c'est-à-dire
/bin/rm -fr johnnyo connor
). De cette façon, vous pouvez annuler votre expression rationnelle et l'essayer à nouveau avec une version plus fiable. Name mangling est connu pour cela, car il est difficile de prendre en charge tous les cas délicats tels que Van Gogh, O'Connors, St. Clair, Smith-Wesson.Avoir
set hlsearch
est utile pour celavim
, car cela mettra en évidence tous les matchs, de sorte que vous puissiez facilement le repérer s'il ne correspond pas, ou les matchs de manière non intentionnelle.Une fois que votre expression rationnelle est parfaite et qu'elle capture tous les cas que vous pouvez tester / penser, je la convertis généralement en une expression sed afin qu'elle puisse être entièrement automatisée pour une autre exécution.
Dans les cas où le nombre de lignes d’entrée vous empêche de procéder à une inspection visuelle, il est vivement recommandé d’envoyer la commande à l’écran (ou, mieux encore, un journal) avant son exécution. Par conséquent, s’il se produit une erreur, vous savez exactement quelle commande a été causée. ça échoue. Ensuite, vous pouvez revenir à votre expression rationnelle originale et ajuster une fois de plus.
la source
Si un programme ignore le canal mais accepte les fichiers comme arguments, vous pouvez simplement le pointer vers le fichier spécial
/dev/stdin
.Je ne connais pas bien Java, mais voici un exemple de la façon dont vous le feriez pour bash:
Le $ est nécessaire pour que bash se traduise
\n
en nouvelles lignes. Je ne sais pas pourquoi.la source
Je préfère ceci - permettant des commandes sur plusieurs lignes et un code clair
ref https://stackoverflow.com/a/3891678/248616
la source
Ici, un copypaste que vous pouvez utiliser immédiatement:
L'élément de la liste sera placé là où se trouve {} et le reste de la commande et des paramètres seront utilisés tels quels.
la source