Использование xargs с вводом из файла


41

Скажем, у меня есть файл со следующим

bob
john
sue

Теперь они непосредственно corrospond к (в данном случае) модель URL , такие как http://example.com/persons/bob.tar, john.tar, sue.tar.

Я хотел бы взять эти строки и провести их через xargs. Я не знаю, что передается команде, хотя выполняется. Как получить доступ к параметру либо из приглашения (скажем, я хочу просто отобразить каждую строку, как cat file | xargs echo $PARAM), либо из сценария bash.


Я не совсем понимаю вопрос, извините. В частности, я не уверен, что означает «я не знаю, что передается выполняемой команде»
Майкл Мрозек

1
@Michael: Когда вы просматриваете список, xargsон разбивает его на строки и передает каждую строку в команду, верно? Как я могу получить доступ к этому, если мне нужно сказать что-то вроде cat file | xargs curl http://example.com/[PASSED FROM FILE].tar?
Джош К

Ответы:


70

Майкл ответ правильный, и должен решить вашу проблему. Бег

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

загрузит файлы, bob.tar john.tar. sue.tarкак и ожидалось.

НО : кошка здесь бесполезна

скорее используйте:

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

1
В моем примере с одним файлом это может быть не идеально, однако,cat xaa xab xac xad ... xargs ...
Джош К

10
@Josh По какой-то причине люди, как правило, очень серьезно относятся к ненужному использованию кошки; За меня уже дважды проголосовали
Майкл Мрозек

2
для записи, вы получили +1 от меня. Я думаю, что использование catдействительно хорошо, просто хотел бы добавить больше информации ... :)
Stefan

Конечно, это должно быть xargs -I % curl …( опция xargs before curlи ее параметры / аргументы). По крайней мере xargs curl -I %(где -I %это подразумевается как опция для xargs , а не curl ) не является переносимым.
Крис Джонсен

@ Крис, хороший улов, тнкс. исправлено.
Стефан

16

Я думаю, вы спрашиваете, как вставить отдельные строки, извлеченные из xargs'stdin, в середину команды, вместо того, чтобы просто вставлять ее в конец всегда. Если это так, -Iфлаг принимает replacement-stringаргумент; xargsзатем заменим replacement-stringв команде строку, прочитанную из stdin:

$ cat file | xargs -I foobar curl http://example.com/foobar.tar

Хорошо, как насчет curl http://example.com/foobar.tar > foobar.tar?
Джош К

2
@ Джош К: >это оболочка конструкций, и не будет работать для xargs. С другой стороны, curl -oбудет записывать в именованный файл вместо stdout, как, например, то wget, что делает, так что это, вероятно, то, что вы хотели бы использовать здесь.
Эфимент

9
$ man xargs
...
       --arg-файл = файл
       -файл
              Чтение элементов из файла вместо стандартного ввода. Если вы используете это
              опция, стандартный ввод остается неизменным при выполнении команд. Другие-
              мудро, stdin перенаправляется из / dev / null.
...

Вы также можете установить --delimiter=/ -dна '\n'.


С другой стороны, если вы просто пытаетесь превратить каждую строку в файле в URL,

Файл $ sed -e #. * # http: //example.com/persons/&.tar# '

будет делать, и если вы хотите получить все из них, просто передать это в .| wget -i


8

Другой способ с циклом оболочки:

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

Вы также можете запустить каждую итерацию в фоновом режиме, добавив &перед последней точкой с запятой - для очень больших загрузок это может быть удобно


2
Вы попали в одну из классических ошибок ! <- неработающая ссылка, вот кэшированная версия: Бесполезное использование награды Cat .
Сорпигал

@Sorpigal Этот URL не работает. Что такое «Классическая ошибка»?
starbeamrainbowlabs

@starbeamrainbowlabs - бесполезное использование кошки, я поместил кэшированную версию этой ссылки в комментарии выше.
СЛМ

@starbeamrainbowlabs: Я специально ссылался на Dangerous Backticks , но использование cat также не нужно, если вы переходите на конструкцию while:while IFS= read i ; do curl ... ; done < file
Sorpigal


1

while read VAR; do ... done цикл простой, но очень универсальный:

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

0

Это более общая версия ответа Стефана, но я использую awk в середине, чтобы подготовить точную «строку», которую я хотел бы выполнить xargs. И тогда xargs использует bash, чтобы выполнить настоящую «работу».

Это немного излишне для этого примера, но это общее решение, которое с некоторыми изменениями может решить многие проблемы ...

cat file | awk '{print "curl http://example.com/persons/"$1".tar"}' | xargs -0 bash -c
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.