Używanie xargs z danymi wejściowymi z pliku

41

Powiedz, że mam plik z następującymi informacjami

bob
john
sue

Teraz te bezpośrednio corrospond do (w tym przypadku) wzór URL, takich jak http://example.com/persons/bob.tar, john.tar, sue.tar.

Chciałbym wziąć te linie i je przejrzeć xargs. Nie wiem jednak, co jest przekazywane do wykonywanego polecenia. Jak uzyskać dostęp do parametru albo z wiersza poleceń (powiedzmy, że chcę po prostu powtórzyć każdy wiersz jak cat file | xargs echo $PARAM) lub ze skryptu bash.

Josh K.
źródło
Przepraszam, nie podążam za pytaniem. W szczególności nie jestem pewien, co znaczy „nie wiem, co jest przekazywane do wykonywanego polecenia”
Michael Mrozek
1
@Michael: Kiedy przeglądasz listę xargs, dzieli ją według linii i podaje każdą linię do polecenia, prawda? Jak uzyskać do niego dostęp, jeśli muszę coś powiedzieć cat file | xargs curl http://example.com/[PASSED FROM FILE].tar?
Josh K

Odpowiedzi:

70

Odpowiedź Michaela jest słuszna i powinna rozwiązać twój problem. Bieganie

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

pobierze pliki bob.tar john.tar. sue.tarzgodnie z oczekiwaniami.

ALE : kot tutaj jest bezużyteczny

raczej użyj:

<file xargs -I % curl http://example.com/persons/%.tar
Stefan
źródło
1
W moim przykładzie z jednym plikiem może to jednak nie być idealnecat xaa xab xac xad ... xargs ...
Josh K
10
@Josh Z jakiegoś powodu ludzie bardzo poważnie traktują niepotrzebne użycie kota; Zostałem już dwukrotnie za nią oceniony
Michael Mrozek
2
dla przypomnienia, masz ode mnie +1. Myślę, że używanie catjest w porządku, po prostu dodaj więcej informacji ... :)
Stefan,
Z pewnością tak powinno być xargs -I % curl …( wcześniej opcja xargscurl i jej opcje / argumenty). Przynajmniej xargs curl -I %(gdzie -I %ma to być opcja xargs , a nie curl ) nie jest przenośny.
Chris Johnsen,
@Chris, nice catch, tnx. naprawiony.
Stefan
16

Myślę, że pytasz, jak wstawić poszczególne linie wyciągnięte ze xargs'stdin w środku polecenia, zamiast po prostu wklejać je zawsze na końcu. Jeśli tak, -Iflaga przyjmuje replacement-stringargument; xargszastąpi replacement-stringw poleceniu wiersz odczytany ze standardowego wejścia:

$ cat file | xargs -I foobar curl http://example.com/foobar.tar
Michał Mrożek
źródło
Dobra, a co powiesz na curl http://example.com/foobar.tar > foobar.tar?
Josh K
2
@Josh K: >to konstrukcja powłoki i nie będzie działać xargs. Z drugiej strony, curl -onapisze do nazwanego pliku zamiast standardowego wyjścia, tak jak to wgetrobi, więc prawdopodobnie tego właśnie chciałbyś użyć tutaj.
ephemient
9
$ man xargs
...
       --arg-file = plik
       -plik
              Czytaj elementy z pliku zamiast standardowego wejścia. Jeśli tego użyjesz
              opcja stdin pozostaje niezmieniona po uruchomieniu poleceń. Inny-
              mądre, stdin jest przekierowywany z / dev / null.
...

Możesz także ustawić --delimiter=/ -dna '\n'.


Z drugiej strony, jeśli próbujesz po prostu zamienić każdą linię w pliku na adres URL,

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

zrobi, a jeśli chcesz pobrać je wszystkie, po prostu włóż to do .| wget -i

efemeryczny
źródło
8

inny sposób z zapętleniem powłoki:

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

możesz także uruchomić każdą iterację w tle, dodając &przed ostatnim średnikiem - w przypadku bardzo dużych pobrań może to być przydatne

Brad Clawsie
źródło
2
Masz spadł na jeden z klasycznych błędów ! <- niedziałający link, tutaj jest buforowane wersja: Useless Zastosowanie nagrody Cat .
Sorpigal,
@Sorpigal Ten adres URL jest uszkodzony. Co to jest „Classic Blunder”?
starbeamrainbowlabs,
@starbeamrainbowlabs - bezużyteczne korzystanie z kota, umieściłem wersję tego linku w pamięci podręcznej w komentarzu powyżej.
slm
@starbeamrainbowlabs: W szczególności łączyłem się z Niebezpiecznymi Backticksami , ale użycie kota jest również niepotrzebne, jeśli zmienisz konstrukcję na jakiś czas:while IFS= read i ; do curl ... ; done < file
Sorpigal
3

Dzięki GNU Parallel możesz:

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

Lub:

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

Obejrzyj wideo wprowadzające do GNU Parallel, aby dowiedzieć się więcej: http://www.youtube.com/watch?v=OpaiGYxkSuQ

Ole Tange
źródło
1

while read VAR; do ... done Pętla jest prosta, ale bardzo wszechstronna:

while read word; do wget http://example.com/persons/$word; done < file
musiphil
źródło
0

To jest bardziej ogólna wersja odpowiedzi Stefana, ale używam awk w środku, aby przygotować dokładnie „ciąg”, który chciałbym wykonać xargs. A następnie xargs używa bash do wykonania „pracy”.

W tym przykładzie jest to trochę przesada, ale jest to ogólne rozwiązanie, które po pewnych modyfikacjach może rozwiązać wiele problemów ...

cat file | awk '{print "curl http://example.com/persons/"$1".tar"}' | xargs -0 bash -c
Johan
źródło