xargs --replace / -I для отдельных аргументов

10

Я пытаюсь использовать xargs для запуска команды для каждого предоставленного аргумента, но, к сожалению, флаг --replace / -I, похоже, не работает должным образом при сопряжении с -n. Кажется, {} расширится до полного списка аргументов, считываемых из stdin, независимо от опции -n.

К сожалению, все примеры в Интернете, похоже, относятся к командам (mv, cp, rm), которые будут принимать несколько аргументов при раскрытии {}.

Например, при запуске:

echo a b c d | xargs -n 1 -I {} echo derp {}

Выход:

derp a b c d

Но я ожидал:

derp a
derp b
derp c
derp d

Однако запуск его без -I {} дает ожидаемый результат:

echo a b c d | xargs -n 1 echo derp
derp a
derp b
derp c
derp d

Есть ли способ добиться этого с помощью xargs? Мое конечное намерение состоит в том, чтобы использовать его для запуска нескольких (parralel) сессий ssh, например

echo server{1..90} | xargs -n 1 -P 0 -I {} ssh {} 'echo $SOME_HOST_INFO'

Я бегу xargs (GNU findutils) 4.4.2на RHEL 6.3.

Андре Фернандес
источник
2
Интересно, что это работает так, как вы собираетесь с BSD xargs, но не с GNU xargs.
Slhck
1
man xargsна -I: Also, unquoted blanks do not terminate input items; instead the separator is the newline character. Implies -x and -L 1.так он ведет себя как задумано.
Даниэль Бек
@ Андре, так как ты намереваешься запускать taks параллельно, ты посмотрел на GNU параллельно? Это делает работу хорошо. Отказ от ответственности: я упаковываю это для Debian.
rbrito
Параллельная GNU показалась хорошей заменой, но, к сожалению, я не могу установить ее на этот конкретный хост.
Андре Фернандес
@ AndréFernandes Можете ли вы уточнить, если ваша причина не покрыта oletange.blogspot.dk/2013/04/why-not-install-gnu-parallel.html
Ole Tange

Ответы:

5

Вы можете повторить с новой строки, чтобы достичь ожидаемого результата. В вашем случае с расширением сервера это будет:

$ echo -e server{1..4}"\n" | xargs -I{} echo derp {}
derp server1
derp server2
derp server3
derp server4
ahilsend
источник
Идея новой строки обходит эту проблему (только не в вашем конкретном примере): echo server {1..4} | tr '' '\ n' | xargs -I {} echo derp {} сумасшедший сервер1 сумасшедший сервер2 сумасшедший сервер3 сумасшедший сервер4
Андре Фернандес
Извините, проверил это zsh... Исправил мой ответ. echoнужна -eопция.
Ахилсенд
2

Вы можете использовать дополнительную трубу, как это,

echo a b c d | xargs -n1 | xargs -I{} echo derp {}
derp a
derp b
derp c
derp d

Промежуточное использование xargs 'echos' каждой буквы 'abcd' индивидуально из-за опции '-n1'. Это помещает каждую букву в отдельной строке, как это,

echo a b c d | xargs -n1
a
b
c
d 

Важно понимать, что при использовании -I (замена строки) xargs подразумевает -L, который выполняет служебную команду (в вашем случае echo) один раз в строке. Кроме того, вы не можете использовать -n с -L, поскольку они являются взаимоисключающими.

synergy77
источник