Передача аргумента нескольким командам в одной строке

10

Я хотел бы иметь возможность запускать несколько команд для одного файла в одной строке. То, как я сейчас делаю это:

commandA file && commandB file && perl -ne '...' file

Мой инстинкт интуиции говорит мне, что должен быть способ предоставить аргумент имени файла только один раз и передать его обеим командам одновременно xargsили что-то подобное:

find file | xargs commandA && xargs commandB && xargs perl -ne '...'

Когда я пытаюсь это сделать, запускается только первая команда. Как я могу достичь того, что я хочу сделать?

Зайд
источник

Ответы:

12

Вы можете определить локальную переменную для этого:

f=file; commandA $f && commandB $f && ...

Вы также можете выполнить все безоговорочно (замена &&на ;) или параллельно (замена &&на &).

Кроме того, вы также можете использовать расширение истории оболочки для ссылки на предыдущие аргументы:

commandA file && commandB !:1 && ...
maxschlepzig
источник
Не совсем то, что я имел в виду, но это интересная альтернатива.
Заид
Что не так с этим ответом?
Крис
Это действительно круто! Есть ли способ не определять новую переменную?
пользователь
@ пользователь, я добавил альтернативу.
maxschlepzig
8

Для оболочек, таких как Bash, Korn и Z, которые имеют подстановку процессов, вы можете сделать это:

find file | tee >(xargs commandA) >(xargs commandB) >(xargs perl -ne '...')
Приостановлено до дальнейшего уведомления.
источник
2

Вы можете использовать xargs для создания командной строки, например:

echo file | xargs -i -- echo ls -l {}\; wc -l {}

Просто запишите вышеприведенное в bash, чтобы запустить его:

echo file | xargs -i -- echo ls -l {}\; wc -l {} | bash

Расширение примера на все файлы * .c в текущем каталоге (экранирование ls здесь для предотвращения подстановки псевдонимов оболочки):

\ls -1 *.c | xargs -i -- echo ls -l {}\; wc -l {} | bash
frielp
источник
Используйте это, чтобы получить список всех файлов, содержащихся в каталогах, где имя похоже на «enums»: find . -name "*enums*" | xargs -i echo -e echo {}\; ls -lh {}\; echo -e '\n\n' | bash
Matt Lachman
1

Я бы не стал голосовать за это сам. Это глупо и опасно, но в интересах перечисления способов сделать это есть:

for cmd in "commandA" "commandB" "perl -ne '...'" ; do eval $cmd file ; done

радостный
источник