Utiliser xargs avec l'entrée d'un fichier

41

Dis que j'ai un fichier avec les éléments suivants

bob
john
sue

Maintenant , ceux - ci directement correpondre (dans ce cas) modèle d'URL tels que http://example.com/persons/bob.tar, john.tar, sue.tar.

Je voudrais prendre ces lignes et les parcourir xargs. Je ne sais pas ce qui est passé à la commande en cours d'exécution cependant. Comment puis-je accéder au paramètre soit à l'invite (disons que je veux simplement faire écho chaque ligne comme cat file | xargs echo $PARAM) ou à partir d'un script bash.

Josh K
la source
Je ne suis pas tout à fait la suite de la question, désolé. En particulier, je ne suis pas sûr de ce que "je ne sais pas ce qui est transmis à la commande en cours d'exécution" signifie
Michael Mrozek
1
@ Michael: Lorsque vous parcourez une liste, xargselle la divise par ligne et introduit chaque ligne dans une commande, n'est-ce pas? Comment puis-je accéder à cela si j'ai besoin de dire quelque chose comme cat file | xargs curl http://example.com/[PASSED FROM FILE].tar?
Josh K

Réponses:

70

La réponse de Michael est juste et devrait régler votre problème. Fonctionnement

cat file | xargs -I % curl http://example.com/persons/%.tar

téléchargera les fichiers bob.tar john.tar. sue.tarcomme prévu.

MAIS : le chat ici est inutile

plutôt utiliser:

<file xargs -I % curl http://example.com/persons/%.tar
Stefan
la source
1
Dans mon exemple de fichier, cela peut ne pas être idéal, cependantcat xaa xab xac xad ... xargs ...
Josh K
10
@ Josh Pour une raison quelconque, les gens ont tendance à prendre très au sérieux les utilisations inutiles du chat ici; J'ai été voté à deux reprises pour cela
Michael Mrozek
2
pour mémoire, vous avez obtenu un +1 de ma part. Je pense que l’utilisation catest très bien, je voudrais juste ajouter plus d’informations ... :)
Stefan
Cela devrait sûrement être xargs -I % curl …( option xargs avant curlet ses options / arguments). À tout le moins xargs curl -I %(où -I %est destiné en tant qu'option à xargs , pas curl ) n'est pas portable.
Chris Johnsen
@ Chris, belle prise, TNX. fixé.
Stefan
16

Je pense que vous demandez comment insérer les lignes individuelles extraites de xargs'stdin au milieu d'une commande, au lieu de simplement les coller à la fin. Si c'est le cas, le -Idrapeau prend un replacement-stringargument; xargsremplacera alors replacement-stringdans la commande la ligne lue dans stdin:

$ cat file | xargs -I foobar curl http://example.com/foobar.tar
Michael Mrozek
la source
D' accord, que diriez - vous curl http://example.com/foobar.tar > foobar.tar?
Josh K
2
@Josh K: >est une construction de shell et ne fonctionnera pas xargs. D'autre part, curl -oécrira dans un fichier nommé plutôt que sur stdout, comme ce qui se wgetpasse, c'est probablement ce que vous voudriez utiliser ici.
éphémère
9
$ man xargs
...
       --arg-file = fichier
       -un fichier
              Lire les éléments du fichier au lieu de l'entrée standard. Si vous utilisez cette
              En option, stdin reste inchangé lorsque les commandes sont exécutées. Autre-
              sage, stdin est redirigé depuis / dev / null.
...

Vous pouvez définir --delimiter=/ -dà '\n'aussi bien.


D'autre part, si vous essayez simplement de transformer chaque ligne du fichier en une URL,

$ sed -e 's #. * # http: //example.com/persons/&.tar#' fichier

va faire, et si vous voulez aller tous les chercher, il suffit de le diriger dans .| wget -i

éphémère
la source
8

une autre façon de boucler en shell:

for i in `cat file`; do curl -I http://foo.com/$i; done

vous pouvez également exécuter chaque itération en arrière-plan en ajoutant &avant le dernier point-virgule - pour les très gros téléchargements, cela peut être pratique

Brad Clawsie
la source
2
Vous avez craqué pour l'un des gaffes classiques ! <- lien brisé, voici une version en cache: Utilisation inutile de Cat Award .
Sorpigal
@Sorpigal Cette URL est cassée. Qu'est-ce que la "gaffe classique"?
starbeamrainbowlabs
@starbeamrainbowlabs - utilisation inutile de chat, j'ai mis une version en cache de ce lien dans le commentaire ci-dessus.
slm
@starbeamrainbowlabs: Je faisais spécifiquement un lien vers Dangerous Backticks , mais l'utilisation de chat est également inutile si vous passez à une construction while:while IFS= read i ; do curl ... ; done < file
Sorpigal
3

Avec GNU Parallel, vous pouvez faire:

cat urls | parallel curl {} ">" {/}

Ou:

cat persons | parallel curl http://example.com/persons/{}.tar ">" {}.tar

Regardez la vidéo d'introduction de GNU Parallel pour en savoir plus: http://www.youtube.com/watch?v=OpaiGYxkSuQ

Ole Tange
la source
1

while read VAR; do ... done la boucle est simple mais très polyvalente:

while read word; do wget http://example.com/persons/$word; done < file
musiphil
la source
0

Ceci est une version plus générale de la réponse de Stefan: s, mais j’utilise awk au milieu pour préparer la "chaîne" exacte que j’aimerais que xargs exécute. Et puis xargs utilise bash pour faire le "travail" réel.

C'est un peu exagéré pour cet exemple, mais c'est une solution générale qui, avec quelques modifications, peut résoudre de nombreux problèmes ...

cat file | awk '{print "curl http://example.com/persons/"$1".tar"}' | xargs -0 bash -c
Johan
la source