Я хочу ввести каждый каталог, перенастроенный командой ls и выполнить скрипт.
Я пробовал это (и многое другое), но он просто не работает
ls | awk '{print $1" && pwd"}' | xargs cd
Как сделать это без цикла?
find . -type d -exec bash -c 'cd "$0" && pwd' {} \;
Смените pwd для своего скрипта. И . для имени корневого каталога, если это не «текущий» каталог.
Вы должны обернуть предложение exec в bash -c "..." из-за того, как работает -exec. cd не существует в его ограниченной среде, но, как вы можете видеть, запустив приведенную выше команду, когда вы приводите bash для выполнения задания, все работает так, как было предсказано.
Edit: I'm не уверен, почему 2011 Оли не думал о -execdir, но это, вероятно, более быстрое решение:
find . -type d -execdir pwd \;
Команда find
Команда find довольно удобна. Он может генерировать список файлов или директив в или ниже указанного каталога, а также может выполнять команду для каждого элемента в этом списке результатов. (Примечание: если вы используете многопользовательскую систему, обязательно прочитайте раздел соображений безопасности документации Findutils для команды find.)
Параметры команды find, которые нам нужны, тип 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. может быть, это поможет u
Просто для любопытства я попытался взять ваш пример и заставить его работать. Нет смысла использовать эту технику вместо команды find.
Примечание: благодаря указанию enzotib, это не работает для имен каталогов, содержащих пробелы или любые другие символы, которые делают awk считают, что имя состоит из нескольких полей.Чтобы сделать ваш пример, нужно сделать несколько настроек. Но сначала посмотрите на код:
ls -l | grep ^d | awk '{print $NF}' | xargs -n 1 bash -c 'cd $0; ls'
Первые две команды удостоверяются, что перечислены только каталоги. Поскольку длинный список ls содержит d в качестве первого символа для каталогов, команда grep выбирает только эти строки.
С awk в каждой строке отображается только последний столбец. NF - встроенная переменная в awk, содержащая максимальное количество полей. Таким образом, печать $NF отображает последнее поле.
Наконец, xargs необходимо приручить для запуска указанного скрипта только с одним параметром. (Я знаю этот вид - поражения его цели.) В противном случае сценарий не мог быть запущен для каждого каталога без цикла for.
И чтобы обойти встроенный барьер cd, мы вызываем [ f13] с -c. Также обратите внимание, что $0 становится первым параметром вместо $1.
Другая альтернатива:
for directory in *
do
(cd $directory && awk '{print $1" && pwd"}')
done
Вы не должны разбирать ls в первую очередь.
Вы можете использовать для этого и его -execdir параметр GNU find, например:
find . -type d -execdir realpath "{}" ';'
] или более практичный пример:
find . -name .git -type d -execdir git pull -v ';'
и здесь версия с -exec:
find . -type d -print0 | xargs -0 -I% sh -c 'cd "%" && pwd && echo Do stuff'
Дополнительные примеры см. в: не должны разбираться ls в SO