Как применить команду оболочки к каждой строке вывода команды? - PullRequest
162 голосов
/ 26 апреля 2010

Предположим, у меня есть вывод команды (например, ls -1):

a
b
c
d
e
...

Я хочу применить команду (скажем, echo) к каждой, по очереди. Э.Г.

echo a
echo b
echo c
echo d
echo e
...

Какой самый простой способ сделать это в bash?

Ответы [ 8 ]

184 голосов
/ 26 апреля 2010

Вероятно, проще всего использовать xargs. В вашем случае:

ls -1 | xargs -L1 echo
136 голосов
/ 26 апреля 2010

Вы можете использовать базовую операцию prepend в каждой строке:

ls -1 | while read line ; do echo $line ; done

Или вы можете передать вывод в sed для более сложных операций:

ls -1 | sed 's/^\(.*\)$/echo \1/'
8 голосов
/ 12 февраля 2014

Вы на самом деле можете использовать sed для этого, при условии, что это GNU sed.

... | sed 's/match/command \0/e'

Как это работает:

  1. Заменить совпадение на командное совпадение
  2. При замене Выполнить команду
  3. Заменить замещенную строку выводом команды.
8 голосов
/ 26 апреля 2010

Вы можете использовать для цикла :

for file in * ; do
   echo "$file"
done

Обратите внимание, что если рассматриваемая команда принимает несколько аргументов, то использование xargs почти всегда более эффективно, так как требует вызова рассматриваемой утилиты один раз, а не несколько раз.

3 голосов
/ 26 апреля 2010
for s in `cmd`; do echo $s; done

Если cmd имеет большой вывод:

cmd | xargs -L1 echo
2 голосов
/ 19 августа 2017

XARGS не с обратной косой чертой, кавычки. Это должно быть что-то вроде

ls -1 |tr \\n \\0 |xargs -0 -iTHIS echo "THIS is a file."

xargs -0 опция:

-0, --null
          Input  items are terminated by a null character instead of by whitespace, and the quotes and backslash are
          not special (every character is taken literally).  Disables the end of file string, which is treated  like
          any  other argument.  Useful when input items might contain white space, quote marks, or backslashes.  The
          GNU find -print0 option produces input suitable for this mode.

ls -1 завершает элементы символами новой строки, поэтому tr переводит их в нулевые символы.

Этот подход примерно в 50 раз медленнее, чем итерация вручную с for ... (см. Майкл Аарон Сафян * ответ 1015 * с) (3,55 с против 0,066 с). Но для других команд ввода, таких как locate, find, чтение из файла (tr \\n \\0 <file) или аналогичных, вы должны работать с xargs следующим образом.

1 голос
/ 23 апреля 2014

Лучший результат для меня:

ls -1 | xargs -L1 -d "\n" CMD
0 голосов
/ 01 ноября 2018

Мне нравится использовать gawk для запуска нескольких команд в списке, например

ls -l | gawk '{system("/path/to/cmd.sh "$1)}'

однако побег от убегающих персонажей может стать немного волосатым.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...