81 votes

xargs avec plusieurs arguments

J'ai une entrée source, input.txt

a.txt
b.txt
c.txt

Je veux introduire ces données dans un programme comme le suivant :

my-program --file=a.txt --file=b.txt --file=c.txt

J'essaie donc d'utiliser xargs mais sans succès.

cat input.txt | xargs -i echo "my-program --file"{}

Il donne

my-program --file=a.txt
my-program --file=b.txt
my-program --file=c.txt

Mais je veux

my-program --file=a.txt --file=b.txt --file=c.txt

Une idée ?

5voto

maharvey67 Points 1015

Voici une solution utilisant sed pour trois arguments, mais elle est limitée en ce qu'elle applique la même transformation à chaque argument :

cat input.txt | sed 's/^/--file=/g' | xargs -n3 my-program

Voici une méthode qui fonctionnera pour deux args, mais qui offre plus de flexibilité :

cat input.txt | xargs -n 2 | xargs -I{} sh -c 'V="{}"; my-program -file=${V% *} -file=${V#* }'

3voto

Adam Badura Points 1517

Je suis tombé sur un problème similaire et j'ai trouvé une solution qui, à mon avis, est plus belle et plus propre que celles présentées jusqu'à présent.

La syntaxe pour xargs avec laquelle j'ai terminé serait (pour votre exemple) :

xargs -I X echo --file=X

avec une ligne de commande complète étant :

my-program $(cat input.txt | xargs -I X echo --file=X)

qui fonctionnera comme si

my-program --file=a.txt --file=b.txt --file=c.txt

a été fait (en fournissant input.txt contient les données de votre exemple).


En fait, dans mon cas, je devais d'abord trouver les fichiers et les trier, donc ma ligne de commande ressemble à ceci :

my-program $(find base/path -name "some*pattern" -print0 | sort -z | xargs -0 -I X echo --files=X)

Quelques détails qui pourraient ne pas être clairs (ils ne l'étaient pas pour moi) :

  • some*pattern doit être cité, car sinon l'interpréteur de commandes le développerait avant de le transmettre à find .
  • -print0 entonces -z et enfin -0 utiliser la séparation nulle pour assurer un traitement correct des fichiers comportant des espaces ou d'autres noms câblés.

Notez cependant que je ne l'ai pas encore testé en profondeur. Bien que cela semble fonctionner.

2voto

Burton Samograd Points 2466

Xargs ne fonctionne pas de cette façon. Essayez :

  myprogram $(sed -e 's/^/--file=/' input.txt)

1voto

aioobe Points 158466

C'est parce que echo imprime une nouvelle ligne. Essayez quelque chose comme

echo my-program `xargs --arg-file input.txt -i echo -n " --file "{}`

1voto

HoNgOuRu Points 367

Je cherchais une solution pour ce problème précis et je suis arrivé à la conclusion de coder une script dans le midle .

pour transformer la sortie standard de l'exemple suivant, utilisez l'option -n '. \n Délimiteur

exemple :

 user@mybox:~$ echo "file1.txt file2.txt" | xargs -n1 ScriptInTheMiddle.sh

 inside the ScriptInTheMidle.sh:
 !#/bin/bash
 var1=`echo $1 | cut -d ' ' -f1 `
 var2=`echo $1 | cut -d ' ' -f2 `
 myprogram  "--file1="$var1 "--file2="$var2 

Pour que cette solution fonctionne, vous devez avoir un espace entre ces arguments file1.txt et file2.txt, ou n'importe quel délimiteur que vous choisissez, une dernière chose, à l'intérieur du script assurez-vous que vous cochez -f1 et -f2 car ils signifient "prendre le premier mot et prendre le deuxième mot" en fonction de la position du premier délimiteur trouvé (les délimiteurs peuvent être ' ' ;' '.' ce que vous voulez entre guillemets simples). Ajoutez autant de paramètres que vous le souhaitez.

Problème résolu en utilisant xargs, cut , et quelques scripts bash.

A la vôtre !

si vous voulez passer par là, j'ai quelques conseils utiles http://hongouru.blogspot.com

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