Verwenden von Xargs mit Eingaben aus einer Datei

41

Angenommen, ich habe eine Datei mit den folgenden Angaben

bob
john
sue

Nun sind diese direkt corrospond zu (in diesem Fall) URL - Muster wie http://example.com/persons/bob.tar, john.tar, sue.tar.

Ich würde diese Zeilen gerne nehmen und durchziehen xargs. Ich weiß jedoch nicht, was an den ausgeführten Befehl übergeben wird. Wie greife ich auf den Parameter entweder über die Eingabeaufforderung (ich möchte einfach jede Zeile wie folgt ausgeben cat file | xargs echo $PARAM) oder über ein Bash-Skript zu?

Josh K
quelle
Ich verfolge die Frage nicht ganz, sorry. Insbesondere bin ich mir nicht sicher, was "Ich weiß nicht, was an den auszuführenden Befehl übergeben wird" bedeutet
Michael Mrozek
1
@Michael: Wenn Sie eine Liste durchlaufen, wird xargssie zeilenweise aufgeteilt und jede Zeile in einen Befehl eingespeist , oder? Wie kann ich darauf zugreifen, wenn ich etwas sagen muss cat file | xargs curl http://example.com/[PASSED FROM FILE].tar?
Josh K

Antworten:

70

Michaels Antwort ist richtig und sollte Ihr Problem lösen. Laufen

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

lädt die Dateien bob.tar john.tar. sue.tarwie erwartet herunter .

ABER : Katze hier ist nutzlos

benutze lieber:

<file xargs -I % curl http://example.com/persons/%.tar
Stefan
quelle
1
In meinem Beispiel mit einer Datei ist dies jedoch möglicherweise nicht idealcat xaa xab xac xad ... xargs ...
Josh K
10
@Josh Aus irgendeinem Grund neigen die Leute dazu, unnötigen Gebrauch von Katzen hier wirklich ernst zu nehmen. Ich bin jetzt zweimal dafür herabgestuft worden
Michael Mrozek
2
Für den Rekord hast du eine +1 von mir bekommen. Ich denke, die Verwendung catist in Ordnung, nur um weitere Informationen hinzuzufügen ... :)
Stefan
Sicher sollte es sein xargs -I % curl …( xargs Option vor curlund seine Optionen / Argumente). Zumindest xargs curl -I %(wo -I %als Option xargs gemeint ist , nicht locken ) ist nicht tragbar.
Chris Johnsen
@ Chris, schöner Fang, tnx. Fest.
Stefan
16

Ich denke, Sie fragen sich, wie Sie die einzelnen Zeilen einfügen sollen, die aus xargs'stdin' in der Mitte eines Befehls gezogen wurden, anstatt sie immer am Ende einzufügen . In diesem -IFall nimmt das Flag ein replacement-stringArgument entgegen. xargsErsetzt dann replacement-stringden Befehl durch die von stdin gelesene Zeile:

$ cat file | xargs -I foobar curl http://example.com/foobar.tar
Michael Mrozek
quelle
Okay, wie wäre es curl http://example.com/foobar.tar > foobar.tar?
Josh K
2
@ Josh K: >ist ein Shell-Konstrukt und funktioniert nicht für xargs. Auf der anderen Seite curl -owird in eine benannte Datei anstelle von stdout geschrieben, wie was wgettut, also ist es wahrscheinlich das, was Sie hier verwenden möchten.
Ephemient
9
$ man xargs
...
       --arg-file = Datei
       -eine Datei
              Liest Elemente aus der Datei anstelle der Standardeingabe. Wenn Sie dies verwenden
              Option, stdin bleibt unverändert, wenn Befehle ausgeführt werden. Andere-
              In diesem Fall wird stdin von / dev / null umgeleitet.
...

Sie können einstellen wollen --delimiter=/ -dzu '\n'auch.


Wenn Sie jedoch nur versuchen, jede Zeile in der Datei in eine URL umzuwandeln,

$ sed -es #. * # http: //example.com/persons/&.tar# 'Datei

wird tun, und wenn Sie alle von ihnen holen wollen, leiten Sie das einfach in .| wget -i

vergänglich
quelle
8

Ein anderer Weg mit Shell-Looping:

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

Sie können jede Iteration auch im Hintergrund ausführen, indem Sie sie &vor dem letzten Semikolon anhängen. Bei sehr großen Downloads kann dies hilfreich sein

Brad Clawsie
quelle
2
Sie haben sich in einen der klassischen Schnitzer verliebt ! <- defekter Link, hier ist eine zwischengespeicherte Version: Useless Use of Cat Award .
Sorpigal
@Sorpigal Diese URL ist kaputt. Was ist der "Classic Blunder"?
Starbeamrainbowlabs
@starbeamrainbowlabs - nutzlose Verwendung von cat, ich habe eine zwischengespeicherte Version dieses Links in den obigen Kommentar eingefügt.
SLM
@starbeamrainbowlabs: Ich habe speziell auf Dangerous Backticks verlinkt , aber die Verwendung von cat ist auch unnötig, wenn Sie zu einem while-Konstrukt wechseln:while IFS= read i ; do curl ... ; done < file
Sorpigal
3

Mit GNU Parallel können Sie:

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

Oder:

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

Sehen Sie sich das Einführungsvideo zu GNU Parallel an, um mehr zu erfahren: http://www.youtube.com/watch?v=OpaiGYxkSuQ

Ole Tange
quelle
1

while read VAR; do ... done loop ist einfach und doch sehr vielseitig:

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

Dies ist eine allgemeinere Version von Stefans Antwort, aber ich verwende awk in der Mitte, um den genauen "String" vorzubereiten, den xargs ausführen soll. Und dann benutzt xargs bash, um die eigentliche "Arbeit" zu erledigen.

Es ist ein bisschen übertrieben für dieses Beispiel, aber es ist eine allgemeine Lösung, die mit einigen Modifikationen viele Probleme lösen kann ...

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