Состав команды в bash - PullRequest
2 голосов
/ 23 июля 2011

Итак, у меня есть эквивалент списка файлов, выводимых другой командой, и он выглядит примерно так:

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 ]

4 голосов
/ 23 июля 2011

Почему бы не прочитать ваш файл и обработать каждую строку отдельно в оболочке? т.е.

fileList=/path/to/my/xmlFileList.txt
cat ${fileList} \
| while read fName ; do
   gzip -d ${fName} | xmlstartlet > ${fName}.new
done 

Надеюсь, это поможет.

1 голос
/ 24 июля 2011

Используйте GNU Parallel:

cat filelist | parallel 'zcat {} | xmlstarlet >{.}.out'

или если вы хотите включить выборку URL-адресов:

cat urls | parallel 'wget -O - {} | zcat | xmlstarlet >{.}.out'

Это легко читать, и вы получаете дополнительное преимущество отработа на процессор выполняется параллельно.Посмотрите вступительное видео, чтобы узнать больше: http://www.youtube.com/watch?v=OpaiGYxkSuQ

0 голосов
/ 23 июля 2011

Если xmlstarlet может работать со стандартным вводом вместо того, чтобы передавать ему имя файла, тогда:

some command | xargs -i -n1 sh -c 'zcat "{}" | xmlstarlet options ...'

Параметр xargs -i означает, что вы можете использовать заполнитель "{}", чтобы указать, где имя файла должноидти.Используйте -n 1, чтобы указать, что xargs должен только одну строку за раз от его ввода.

0 голосов
/ 23 июля 2011

Хотя правильный ответ - тот, который предлагает укрытие (+1), здесь есть однострочный " divertimento ", при условии, что ввод является предложением Андрея (a command, который генерирует список URL): -)

~$ eval $(command | awk '{a=a "wget -O - "$0" | gzip -d | xmlstartlet > $(basename "$0" .gz ).new; " } END {print a}')

Он просто генерирует мультикомандную строку, которая делает wget <a href="http://foo.xml.gz" rel="nofollow">http://foo.xml.gz</a> | gzip -d | xmlstartlet > $(basenname foo.xml.gz .gz).new для каждого из URL-адресов во входных данных; после того, как полученная команда оценена

...