Что такое маски (wildcards) в bash: *, ? и квадратные скобки?
Часто вижу в командах звёздочку, типа rm *.log, и примерно догадываюсь, что это «все файлы». Но что значат ? и [ ]? Хочу разобраться, как правильно работают эти маски (wildcards) в bash, чтобы случайно не удалить лишнее.
ls *.txt
ls file?.txt
ls file[1-3].txt
Что выберет каждая из этих команд?
2 ответа
Это так называемый globbing — оболочка сама подставляет имена подходящих файлов ещё до запуска команды. Основные шаблоны:
*— любое количество любых символов (в том числе ноль).*.txt= все файлы, оканчивающиеся на.txt.?— ровно один любой символ.file?.txtподойдёт подfile1.txt,fileA.txt, но НЕ подfile10.txt(там два символа) и не подfile.txt(там ноль).[...]— один символ из набора.file[1-3].txt=file1.txt,file2.txt,file3.txt. Можно списком:file[abc].txt.
Разберём твои примеры, пусть в папке лежат: a.txt, file1.txt, file2.txt, file10.txt, notes.md.
ls *.txt # a.txt file1.txt file2.txt file10.txt
ls file?.txt # file1.txt file2.txt (file10.txt НЕ попал — две цифры)
ls file[1-3].txt # file1.txt file2.txt
Главный совет по безопасности: перед rm сначала проверь маску через ls или echo:
echo *.log # посмотреть, что именно попадёт
rm *.log # только убедившись
И помни: * сам по себе не трогает скрытые файлы (которые начинаются с точки) — для них нужен явный шаблон вроде .* или .[!.]*.
Важный момент, который ломает новичкам мозг: маски раскрывает оболочка, а не команда. Поэтому если ни один файл не подходит под *.log, bash по умолчанию передаст команде саму строку *.log как есть, и rm ругнётся, что такого файла нет. Ещё: если в имени файла есть пробел, маска всё равно сработает — это безопаснее, чем перечислять имена руками.