Командный состав в баше
Таким образом, у меня есть эквивалент списка файлов, выводимых другой командой, и это выглядит примерно так:
http://somewhere.com/foo1.xml.gz
http://somewhere.com/foo2.xml.gz
...
Мне нужно запустить XML в каждом файле через xmlstarlet, поэтому я делаю ... | xargs gzip -d | xmlstarlet ...
, за исключением того, что я хочу, чтобы xmlstarlet вызывался один раз для каждой строки, входящей в gzip, а не для всех xml-документов, добавленных друг к другу. Возможно ли compose 'gzip -d' 'xmlstarlet ...'
, чтобы xargs предоставлял один аргумент каждой из своих составных функций?4 ответа:
Почему бы не прочитать ваш файл и не обработать каждую строку отдельно в оболочке? то есть
fileList=/path/to/my/xmlFileList.txt cat ${fileList} \ | while read fName ; do gzip -d ${fName} | xmlstartlet > ${fName}.new done
Надеюсь, это поможет.
Используйте GNU Parallel:
cat filelist | parallel 'zcat {} | xmlstarlet >{.}.out'
Или если вы хотите включить выборку URL-адресов:
cat urls | parallel 'wget -O - {} | zcat | xmlstarlet >{.}.out'
Его легко читать,и вы получаете дополнительное преимущество от параллельного выполнения заданий на ЦП. Смотрите вступительное видео, чтобы узнать больше: http://www.youtube.com/watch?v=OpaiGYxkSuQ
Хотя правильный ответ-это тот, который предлагает shelter (+1), вот однострочный "дивертисмент " при условии, что вход-это предложенный Андреем (a
command
, который генерирует список URL): -)~$ eval $(command | awk '{a=a "wget -O - "$0" | gzip -d | xmlstartlet > $(basename "$0" .gz ).new; " } END {print a}')
Он просто генерирует мультикомандную строку, которая делает
wget http://foo.xml.gz | gzip -d | xmlstartlet > $(basenname foo.xml.gz .gz).new
для каждого из URL-адресов во входных данных; после того, как результирующая команда оценена
Если xmlstarlet может работать на stdin вместо того, чтобы передавать ему имя файла, то:
some command | xargs -i -n1 sh -c 'zcat "{}" | xmlstarlet options ...'
Опция xargs
-i
означает, что вы можете использовать заполнитель"{}"
, чтобы указать, куда должно идти имя файла. Используйте-n 1
, чтобы указать, что xargs следует только по одной строке за раз от его входа.