Как выполнить команду на каждом входе, учитывая список входных данных

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

(Ниже приведен надуманный и упрощенный пример того, что я хочу сделать).

ls | xargs echo 'Looking at {}' && cd {} && /bin/do_stuff 

Но это не работает. Как мне это сделать?

2 Solutions collect form web for “Как выполнить команду на каждом входе, учитывая список входных данных”

Это не работает, потому что xargs выполняет свою команду напрямую. Он не принимает строку кода оболочки и передает команду на выполнение оболочки. Фактически, все эти && s интерпретируются оболочкой до xargs даже ls и xargs . Кроме того, {} представляет собой конструкцию, которая find понимает, а не xargs .

(Вы можете использовать -I с xargs чтобы имитировать эту функцию find , если хотите.)

Самый простой способ сделать это с помощью xargs – поместить вашу команду в сценарий оболочки:

 #!/bin/sh echo "Looking at $1" cd $1 /bin/do_stuff 

(Я эффективно заменил ваш && ; поскольку он выглядит так, как echo и cd не могут потерпеть неудачу, если вы запустите это в каталоге, который содержит только другие подкаталоги. Если вам нужно «и» поведение, требуемое исправление для скрипта очевидно.)

Затем запустите этот сценарий оболочки через xargs . Если вы назвали его dostuff.sh :

 $ ls | xargs ./dostuff.sh 

dostuff.sh должен быть отмечен как исполняемый файл, например, с chmod +x dostuff.sh .

Вероятно, есть способ написать все это в одной строке с sh -c , но если вы не можете вспомнить волшебство, чтобы сделать что-то такое, это в основном просто любопытство, не так ли?

xargs – правильный инструмент, но его сложно использовать.

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

 echo hello world | xargs echo 'Looking at' 

запускает echo 'Looking at' hello world . Чтобы запустить команду один раз для каждой строки ввода, используйте xargs -L1 :

 (echo hello; echo world) | xargs -L1 echo 'Looking at' 

Поскольку вы хотите, чтобы xargs запускала команду оболочки, вам нужно заставить ее явно вызывать оболочку.

 (echo hello; echo world) | xargs sh -c 'echo "Looking at $0" && cd "$0" && /bin/do_stuff' 

(Или tcsh -c если вы действительно этого хотите, но приходите один, это 21-й век.)

Вы можете использовать -I {} для интерполяции {} внутри этой команды, но будьте осторожны, что это работает только в том случае, если вход не содержит специальных символов оболочки. Передача ввода в качестве аргумента команды ( $0 выше) имеет то преимущество, что не делает никаких предположений на входе (за xargs -L разделения строк и не содержит конечных пробелов в соответствии с синтаксисом xargs -L ).

В оболочке Bourne / POSIX альтернативный подход, который использует больше строк, но намного более ясный, заключается в использовании цикла вокруг встроенной оболочки read :

 { echo hello; echo world; } | while IFS= read -r line; do echo "Looking at $line" (cd "$line" && /bin/do_stuff) done 

(Обратите внимание, что я выполняю cd в подоболочке, потому что весь цикл выполняется в той же оболочке, и я не хочу изменять рабочий каталог этой оболочки.)

  • настроить цвет ls для каталогов содержат указанные файлы / с
  • Настройка цветов LS с человеко-читаемым скриптом в tcsh
  • Почему мой $ PATH не наследуется вызванным bash?
  • Заменить имя файла с именем папки (csh)
  • Что случилось с этим csh-файлом?
  • название динамического окна из ввода команды (TCSH)
  • `tcsh` повторить с подоболочкой
  • Почему руководство для команды «где» недоступно
  • scp не автозаполняется так же, как другие команды
  • Выражение Grep со специальными именами файлов
  • Как создать каталог для каждого файла в родительском каталоге
  • Interesting Posts

    ssh user @ IP sh <команда> пропущенные переменные среды

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

    Как сообщить systemd о прекращении службы, когда она больше не требуется / требуется

    Использование grep / awk / sed для сортировки и объединения двух файлов

    Какие инструменты позволяют мне отображать man-страницы в формате HTML на веб-сервере?

    Как запустить самую последнюю команду в AIX?

    Как подтвердить аппаратную проблему с сетевой картой?

    Что такое соответствующий UID и GID для владельца файла пакета Debian?

    Как я могу избежать 550 «Relaying denied» с postfix?

    Слияние трех анимаций .gif

    Как перечислять только каталоги, которые не находятся в подкаталоге `.git`?

    Ярлык для быстрого рекурсивного удаления

    почему ssh myLogin @ localhost работает, но ssh root @ localhost нет?

    Сценарий Bash не работает, как ожидалось

    Почему set-o errexit нарушает это выражение read / heredoc?

    Linux и Unix - лучшая ОС в мире.