linux-labs

Вики / Базовые команды

Шаблоны имён (glob) и фигурные скобки

Подстановки оболочки — * ? [] {} — и чем они отличаются от регулярок.

Оболочка сама раскрывает шаблоны имён файлов (globbing) до запуска команды. Это не регулярки — синтаксис другой и проще.

ls *.log                          # все файлы на .log
rm tmp_?                          # tmp_1, tmp_a (один символ)
ls report-[0-9].txt               # report-0.txt … report-9.txt
Шаблон Значение
* любая строка (включая пустую), кроме /
? ровно один символ
[abc] [!abc] один из / любой кроме
[0-9] [a-z] диапазон
** рекурсивно по подкаталогам (при shopt -s globstar)

Фигурные скобки {} — это не glob (раскрываются всегда, даже без файлов):

mkdir -p project/{src,tests,docs}     # три каталога
cp file.conf{,.bak}                   # cp file.conf file.conf.bak (быстрый бэкап!)
mv app.{js,ts}                        # НЕ сработает как rename — это два аргумента
echo {1..5} ; echo {01..10..2}        # 1 2 3 4 5 ; 01 03 05 07 09 (шаг)
echo img-{a,b,c}.png                  # img-a.png img-b.png img-c.png
shopt -s globstar     # ** рекурсивно: ls **/*.log
shopt -s nullglob     # несовпавший glob → пусто (а не сам шаблон)
shopt -s dotglob      # * включает скрытые файлы (.bashrc и т.п.)
shopt -s nocaseglob   # без учёта регистра: *.JPG поймает .jpg
shopt -s extglob      # расширенные: !(*.bak) @(a|b) +(x) *(y) ?(z)
shopt -s failglob     # несовпавший glob → ошибка (строгие скрипты)

extglob-примеры: rm !(*.keep) (всё, кроме .keep), ls @(*.jpg|*.png).

  • glob — для имён файлов в оболочке; * = «что угодно».
  • regex — для содержимого в grep/sed; там * = «0+ повторов предыдущего», а «что угодно» = .*.

Не путай: ls *.txt (glob) ≠ grep '*.txt' (regex — нужно grep '\.txt').

Шаблон не нашёл файлов — команда получила сам шаблон

По умолчанию bash оставляет нераскрытый glob как есть (ls *.xyz → «нет *.xyz»). Включи shopt -s nullglob (исчезает) или failglob (ошибка).

Скрытые файлы не попали в *

* не включает файлы на .. Используй .* отдельно или shopt -s dotglob (осторожно: .* цепляет . и ..).

Пробелы/спецсимволы в именах ломают

Кавычь переменные; для массовой обработки — find -print0 | xargs -0 (см. xargs).

{a,b} не раскрылось

Внутри не должно быть пробелов: {a, b} не сработает. И это не glob — раскрывается до проверки файлов.

*.log  ?  [0-9]  [!a]           # glob: строка / символ / диапазон / кроме
mkdir -p p/{src,tests,docs}     # фигурные скобки
cp file{,.bak}                  # быстрый бэкап
echo {1..5} ; echo {01..10..2}  # последовательности (+шаг)
shopt -s globstar ; ls **/*.log # рекурсивно
shopt -s extglob ; rm !(*.keep) # всё кроме .keep
# glob — имена файлов ; regex — содержимое (grep/sed)

См. также