У меня есть папка с некоторыми каталогами и некоторыми файлами (некоторые скрыты, начиная с точки).
for d in *; do
echo $d
done
будет перебирать все файлы, но я хочу зацикливать только через каталоги. Как мне это сделать?
Вы можете указать косую черту в конце, чтобы соответствовать только каталогам:
for d in */ ; do
echo "$d"
done
[[ -L $d ]]
, является ли $ d символической ссылкой.set -P
влияет только на команды, которые меняют каталог. sprunge.us/TNac[[ -L "$f" ]]
не исключать символические ссылки в этом случае с*/
, вы должны удалить косую черту с[[ -L "${f%/}" ]]
(см. Тест для связи с косой чертой )Вы можете проверить с
-d
:Это один из операторов проверки файлов .
источник
if [[ -d "$f" && ! -L "$f" ]]
исключит символическиеif [[ "$f" = "*" ]]; then continue; fi
Помните, что решение choroba, хотя и элегантное, может вызвать неожиданное поведение, если в текущем каталоге нет доступных каталогов. В этом состоянии, вместо пропуска
for
цикла, bash запустит цикл ровно один раз, гдеd
равно*/
:Я рекомендую использовать следующее для защиты от этого случая:
Этот код будет перебирать все файлы в текущем каталоге, проверять,
f
является ли каталог каталогом, а затем выводить эхо,f
если условие возвращает true. Еслиf
равно*/
,echo $f
не будет выполняться.источник
shopt -s nullglob
.Если вам нужно выбрать более конкретные файлы, чем использовать только каталоги
find
и передать ихwhile read
:Используется
shopt -u dotglob
для исключения скрытых каталогов (илиsetopt dotglob
/unsetopt dotglob
в zsh).IFS=
чтобы избежать разделения имен файлов, содержащих одно из$IFS
, например:'a b'
см. ответ AsymLabs ниже для большего количества
find
вариантовedit:
Если вам нужно создать выходное значение из цикла while, вы можете обойти дополнительный подоболочек с помощью этого трюка:
источник
Вы можете использовать чистый bash для этого, но лучше использовать find:
(найти дополнительно будет включать скрытые каталоги)
источник
shopt -s dotglob
дляbash
включения скрытых каталогов. Ваш также будет включать.
. Также обратите внимание, что-maxdepth
это не стандартная опция (-prune
есть).dotglob
Вариант интересен , ноdotglob
относится только к использованию*
.find .
всегда будет включать скрытые каталоги (и текущий каталог)Это делается для поиска как видимых, так и скрытых каталогов в текущем рабочем каталоге, исключая корневой каталог:
просто перебрать каталоги:
включить символические ссылки в результат:
сделать что-то для каждого каталога (исключая символические ссылки):
чтобы исключить скрытые каталоги:
выполнить несколько команд для возвращаемых значений (очень надуманный пример):
вместо sh -c также можно использовать bash -c и т. д.
источник
... -print0 | xargs -0 ...
если вы не знаете, каковы точные имена.find * | while read file; do ...
Вы можете перебрать все каталоги, включая скрытые каталоги (начиная с точки) в одну строку и несколько команд с помощью:
Если вы хотите исключить символические ссылки:
примечание: использование списка
*/ .*/
работает в bash, но также отображает папки,.
а..
в zsh не показывает их , а выдает ошибку, если в папке нет скрытого файлаБолее чистая версия, которая будет включать скрытые каталоги и исключать ../, будет с опцией dotglob:
(или
setopt dotglob
в зш)Вы можете сбросить дотглоб с
источник
Это будет включать полный путь в каждом каталоге в списке:
источник
Используйте
find
с,-exec
чтобы перебрать каталоги и вызвать функцию в опции exec:Использовать
shopt -s dotglob
илиshopt -u dotglob
включать / исключать скрытые каталогиисточник
Это перечисляет все каталоги вместе с количеством подкаталогов в данном пути:
источник
источник
This
is
one
directory
with
spaces
in
the
name
- но разбирается как несколько.или же:
Вы можете установить его как псевдоним
источник
ls
ответа, основанного на списках каталогов.ls
: mywiki.wooledge.org/ParsingLs