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
Використовуйте * .[!.]* ..?*
триптих та виконайте команду один раз за шаблоном, але лише якщо він щось відповідає. Ця команда виконує лише один раз. Зверніть увагу на те, що позиційні параметри клобовані (в оболонках 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 . -name . -o -exec somecommand {} + -o -type d -prune