Bash, ksh и zsh имеют лучшие решения, но в этом ответе я предполагаю оболочку POSIX.
Шаблон .[!.]*
соответствует всем файлам, которые начинаются с точки, за которой следует не точка. (Обратите внимание, что [^.]
поддерживается некоторыми оболочками, но не всеми, переносимый синтаксис для дополнения набора символов в шаблонах подстановочных знаков [!.]
.) Поэтому он исключает .
и ..
, но также и файлы, которые начинаются с двух точек. Шаблон ..?*
обрабатывает файлы, которые начинаются с двух точек и не просто ..
.
chown -R root .[!.]* ..?*
Это классический шаблон, установленный для соответствия всем файлам:
* .[!.]* ..?*
Ограничением этого подхода является то, что если один из шаблонов ничего не соответствует, он передается команде. В сценарии, когда вы хотите , чтобы соответствовать всем файлам в директории , кроме .
и ..
, есть несколько решений, все из них громоздкими:
Используйте * .*
для перечисления всех записей и исключения .
и ..
в цикле. Один или оба шаблона могут не совпадать, поэтому цикл должен проверять существование каждого файла. У вас есть возможность фильтровать по другим критериям; например, удалите -h
тест, если хотите пропустить висячие символические ссылки.
for x in * .*; do
case $x in .|..) continue;; esac
[ -e "$x" ] || [ -h "$x" ] || continue
somecommand "$x"
done
Более сложный вариант, когда команда запускается только один раз. Обратите внимание, что позиционные параметры являются засоренными (оболочки POSIX не имеют массивов); поместите это в отдельную функцию, если это проблема.
set --
for x in * .[!.]* ..?*; do
case $x in .|..) continue;; esac
[ -e "$x" ] || [ -h "$x" ] || continue
set -- "$@" "$x"
done
somecommand "$@"
Используйте * .[!.]* ..?*
триптих. Опять же, один или несколько шаблонов могут не совпадать, поэтому нам нужно проверить существующие файлы (включая висячие символические ссылки).
for x in * .[!.]* ..?*; do
[ -e "$x" ] || [ -h "$x" ] || continue
somecommand "$x"
done
Используйте * .[!.]* ..?*
tryptich и запускайте команду один раз для каждого шаблона, но только если он соответствует чему-либо. Это запускает команду только один раз. Обратите внимание, что позиционные параметры помечены (у оболочек POSIX нет массивов), поместите это в отдельную функцию, если это проблема.
set -- *
[ -e "$1" ] || [ -h "$1" ] || shift
set -- .[!.]* "$@"
[ -e "$1" ] || [ -h "$1" ] || shift
set -- ..?* "$@"
[ -e "$1" ] || [ -h "$1" ] || shift
somecommand "$@"
Использование find
. С помощью GNU или BSD найти, избежать рекурсии легко с опциями -mindepth
и -maxdepth
. С POSIX find это немного сложнее, но можно сделать. Преимущество этой формы заключается в том, что она позволяет легко запускать команду один раз, а не один раз для файла (но это не гарантируется: если полученная команда слишком длинная, команда будет запущена в нескольких пакетах).
find . -name . -o -exec somecommand {} + -o -type d -prune