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

Я хочу войти в каждый каталог, перенастроенный командой ls, и выполнить скрипт.

Я пытался это (и многие другие), но это просто не работает

ls  | awk '{print $1" && pwd"}' | xargs cd

Как это сделать без цикла for?

5
задан 13 October 2018 в 17:59

7 ответов

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

Но если Вы все еще хотите использовать xargs, возможная альтернатива следующая:

printf '%s\0' */ | xargs -0 -L1 bash -c 'cd -- "$1" && pwd' _

Некоторые примечания:

  1. */ расширяется до списка каталогов в текущей папке, благодаря запаздывающей наклонной черте

  2. printf с \0 (пустой байт), разделяет элементы один для каждой строки

  3. опция -L1 кому: xargs добирается выполняются однажды для каждой входной строки и опции -0 заставляет его разделить вход на пустом байте: имена файлов могут содержать любой символ, команда не повреждается!

  4. bash удаляет двойные кавычки, и передайте его встроенному сценарию как единственный параметр, но cd должен поместить двойные кавычки снова для интерпретации его как единственной строки; использование -- делает cd команда, устойчивая против имен файлов, которые запускаются с дефиса

  5. избегать странного использования $0 в качестве параметра, обычно для помещения первого фиктивного аргумента _

9
ответ дан 13 October 2018 в 17:59
find . -type d -exec bash -c 'cd "$0" && pwd' {} \;

Подкачка pwd для Вашего сценария. И . для имени корневого каталога, если это не "текущий" каталог.

Необходимо перенести исполнительный пункт в bash -c "..." из-за пути -exec работы. cd не существует в его ограниченной среде, но как Вы видите путем выполнения вышеупомянутой команды при введении удара, чтобы сделать задание, все работает, как предсказано.

Править: Я не уверен, почему 2 011 Oli не думали -execdir но это - вероятно, более быстрое решение:

find . -type d -execdir pwd \;
16
ответ дан 13 October 2018 в 17:59

Команда поиска

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

Нам нужны следующие опции команды find: -type d, в котором команда find возвращает имена всех каталогов в указанном пути, и команда -exec '{}' \; который сообщает команда find для запуска результатов. Например:

find /media/music/flac -type d -exec ~/tag-flac-with-rg.sh '{}' \;

Это говорит find найти все каталоги в или ниже пути / media / music / flac и затем запустить скрипт tag-flac-with-rg.sh для каждого найденного каталога. '{}' Заменяется каждым найденным именем каталога и передается в качестве аргумента в скрипт tag-flac-with-rg.sh. \; отмечает конец списка аргументов в сценарии tag-flac-with-rg.sh. может быть, это поможет вам

0
ответ дан 13 October 2018 в 17:59

Только для любопытства я пытался взять Ваш пример и заставить его работать. Нет никакой причины использовать эту технику вместо find команда.

Примечание: Благодаря enzotib для указания на него это не работает на имена каталогов, содержащие пробелы или любые другие символы, которые делают awk думайте, что имя состоит из нескольких полей.

Чтобы заставить Ваш пример работать, несколько тонких настроек должны быть сделаны. Но сначала см. код:

ls -l | grep ^d | awk '{print $NF}' | xargs -n 1 bash -c 'cd $0; ls'

Первые две команды удостоверяются, что только каталоги перечислены. С тех пор ls длинный список содержит a d как первый символ для каталогов, grep команда выбирает только эти строки.

С awk только последний столбец отображен в каждой строке. NF встроенная переменная в awk содержание максимального количества полей. Таким образом печать $NF отображает последнее поле.

Наконец xargs должен был быть приручен для запущения указанного скрипта только с одним параметром за один раз. (Я знаю, что это отчасти побеждает его цель.) Иначе скрипт не мог быть запущен для каждого каталога без для цикла.

И работать вокруг встроенного cd барьер, мы звоним bash с -c. Также отметьте это $0 становится первым параметром вместо $1.

2
ответ дан 13 October 2018 в 17:59

Вы не должны анализировать ls в первую очередь.

Вы можете использовать GNU find для этого и его параметра -execdir, например:

find . -type d -execdir realpath "{}" ';'

или более практический пример:

find . -name .git -type d -execdir git pull -v ';'

и вот версия с [ 116]:

find . -type d -print0 | xargs -0 -I% sh -c 'cd "%" && pwd && echo Do stuff'

Дополнительные примеры см .: Как перейти в каждый каталог и выполнить команду? в SO

0
ответ дан 13 October 2018 в 17:59

Другая альтернатива:

for directory in *
do
  (cd $directory && awk '{print $1" && pwd"}')
done
0
ответ дан 13 October 2018 в 17:59

Может быть, посмотрите на использование find с -exec?

0
ответ дан 13 October 2018 в 17:59

Другие вопросы по тегам:

Похожие вопросы: