Основы Linux от основателя Gentoo. Часть 1 (4/4): Glob-подстановки

Original author: Daniel Robbins, Chris Houser, Aron Griffis
  • Translation
  • Tutorial
Заключительная часть перевода первой части замечательной серии учебных пособий. Предыдущие отрывки по ссылкам: начало, второй и третий.

В данном, четвертом, отрывке рассматривается использование джокеров (wild cards) *, [] и ? для подставления путей по шаблону. А также, подводятся итоги первой части. Enjoy! ;)

Использование джокеров


Знакомство с джокерами


В повседневном использовании Linux часто случается, когда вам нужно выполнить единичную операцию (например rm) на множестве объектов файловой системы за раз. В подобных ситуациях вписывать множество файлов в командную строку, зачастую, довольно обременительно:



$ rm file1 file2 file3 file4 file5 file6 file7 file8

Для решения этой проблемы, вы можете извлечь пользу из встроенной в Linux поддержки джокеров. Эта поддержка также называется «globbing» (по историческим причинам; в русском также известно как «универсализация файловых имен» — прим. пер.), позволяет указать множество файлов за раз, используя шаблон «дикой конкатенации». Bash и другие команды Linux интерпретируют этот шаблон просматривая диск в поисках файлов, которые ему удовлетворяют. Так, если у вас есть файлы file1 до file8 в текущей рабочей директории, то можете их удалить набрав:



$ rm file[1-8]

Или если просто хотите удалить все файлы с именами начинающимися с file, включая сам файл по имени file, вы можете набрать:



$ rm file*

Дикая конкатенация "*" совпадает с любым символом или набором символов, или даже с их отсутствием. Разумеется, glob-джокеры возможно использовать для гораздо большего, чем простое удаление файлов, как мы увидим в дальнейшем.



Неподходящие шаблоны


Если вам необходимо перечислить все объекты файловой системы в /etc, начинающиеся с «g», а также сам g, то можно ввести:



$ ls -d /etc/g*
/etc/gconf /etc/ggi /etc/gimp /etc/gnome /etc/gnome-vfs-mime-magic /etc/gpm /etc/group /etc/group-

А сейчас о том, что случится если вы укажите шаблон, который не подходит ни под один объект файловой системы. В следующем примере мы попытались перебрать все файлы в /usr/bin, которые начинаются с «asdf» и оканчиваются на «jkl», потенциально включая и asdfjkl:



$ ls -d /usr/bin/asdf*jkl
ls: /usr/bin/asdf*jkl: No such file or directory


Вот что случится. Обычно, когда мы задаем шаблон, и если в него укладываются один или несколько файлов в подразумеваемой файловой системе, то bash заменяет наш шаблон на разделенный пробелами список всех подходящих объектов. Однако, когда с шаблоном нет совпадений, bash оставляет переданный аргумент с джокерами как есть. Так вот, затем ls не может найти файл /usr/bin/asdf*jkl и выдает нам ошибку. Основное правило тут такое: glob-шаблоны разворачиваются только если совпадают с объектами файловой системы. В противном случае, остаются не тронутыми и буквально передаются в вызов программы.



Синтаксис джокеров: * и ?


Так, мы уже посмотрели как работает globbing, теперь же стоит рассмотреть синтаксис джокеров. В качестве джокеров используются специальные символы:



* — совпадает с нулевым или большим количеством символов. Это значит: «тут может быть все что угодно, включая и ничего». Примеры:


  • /etc/g* совпадает со всеми файлами в /etc, начинающимися с g и самим файлом g;
  • /tmp/my*1 совпадает со всеми файлами в /tmp, которые начинаются с my и заканчиваются 1, включая файл my1.

? — равен любому одному символу. Примеры:


  • myfile? совпадает с любым файлом, чье имя составляет myfile и следующим за этим какой-либо один символ;
  • /tmp/notes?txt совпадет, например, с /tmp/notes.txt и /tmp/notes_txt, если они существуют.

Синтаксис джокера: []


Этот джокер похож на ?, но более точен. Чтобы его использовать, поместите любые символы, какие вам нужны, внутрь []. Полученное выражение будет удовлетворять любому одному из этих символов. Вы также можете воспользоваться "-", для указания диапазона, и даже комбинации диапазонов. Примеры:


  • myfile[12] совпадет с myfile1 и myfile2. Джокер сработает если хотя бы один из этих файлов существует в текущей директории;
  • [Cc]hange[Ll]og совпадет с Changelog, ChangeLog, changeLog и changelog. Как можете заметить, использование скобочных джокеров очень удобно для указания вариантов с заглавными буквами;
  • ls /etc/[0-9]* покажет все файлы в /etc, начинающиеся с десятичной цифры;
  • ls /tmp/[A-Za-z]* отобразит все файлы в /tmp, которые начинаются с большой или маленькой латинской буквы.

Конструкция [!] эквивалентна конструкции [], за исключением того, что вместо совпадения с символами внутри скобок, она удовлетворяет любому символу, который НЕ перечислен между [! и ]. Пример:


  • rm myfile[!9] удалит все файлы с названием myfile плюс один символ, кроме myfile9.

Предостережения о джокерах


Сейчас несколько предостережений, чтобы быть осторожными во время использования джокеров. Поскольку bash обрабатывает относящиеся к джокерам символы (?, [, ] и *) особым образом, вам надо особенно позаботиться, когда вы пишите аргумент для команды, содержащий эти символы. Например, если вы хотите создать файл, содержащий строку "[fo]*", то следующая команда может не дать желаемого результата:



$ echo [fo]* > /tmp/mynewfile.txt

Если шаблон [fo]* совпадет с какими-либо файлами в текущей рабочей директории, то вы обнаружите их имена внутри /tmp/mynewfile.txt, вместо ожидаемого [fo]*. Решение? Ну, одним из них будет огородить ваши символы в одиночные кавычки, которые сообщат bash не делать никаких раскрытий джокеров в них:



$ echo '[fo]*' > /tmp/mynewfile.txt

Используя этот подход, ваш новый файл будет содержать [fo]* буквально, как и предполагалось. Также, вы можете использовать экранирующую обратную косую черту, чтобы сообщить bash, что [, ] и * должны интерпретироваться буквально, а не как джокеры:



$ echo \[fo\]\* > /tmp/mynewfile.txt

Оба подхода (одиночные кавычки и экранирующая обратная косая черта) работают с одинаковым эффектом. Поскольку мы заговорили про обработку обратной косой черты, то неплохо бы было сейчас прояснить, что на случай, если вы хотите указать \ буквально, можно либо также взять ее в одиночные кавычки, либо набрать \\ (это будет обращено в \).



Примечание:


Двойные кавычки работают также как и одиночные, но всё еще разрешают bash делать некоторую ограниченную обработку. Следовательно, одиночные кавычки — ваш лучший выбор, если вы действительно заинтересованны в буквальной передаче текста в команду. Получить больше информации о раскрытии джокеров можно набрав man 7 glob. Чтобы получить больше информации о кавычках в bash, наберите man 1 bash и прочитайте раздел под названием QUOTING. Если в ваши планы входит сдача экзаменов LPI, то рассматривайте это как свое домашнее задание. =)



Подведение итогов и ссылки на другие ресурсы


Итог


Поздравляем; Вы добрались до конца нашего обзора об основах Linux! Я надеюсь, что это помогло вам укрепить свои фундаментальные познания в Linux. Темы, которые вы здесь изучили, включая основы работы в bash, основные команды Linux, ссылки и джокеры — заложили фундамент для нашего следующего пособия об основах администрирования, в котором мы рассмотрим такие темы, как регулярные выражения, принадлежность и права доступа, управления аккаунтами пользователей, и многое другое.



Продолжая погружаться в эти учебные пособия, вы скоро достигните LPIC Level 1 сертификации от Linux Professional Institute. Говоря об этой сертификации, если это действительно то, в чем вы заинтересованы, мы рекомендуем вам изучить ресурсы из параграфа ниже, которые были внимательно подобраны к материалу освещенному в этом руководстве.



Ссылки


В серии статей «Bash в примерах», Дэниэль показывает как использовать программные конструкции bash для написания ваших собственных bash-скриптов. Эта серия (в основном 1 и 2 части) будет отличной подготовкой для LPIC Level 1:


  • Bash в примерах, Часть 1: Основы программирования в Bourne-again shell — на английском, перевод на русский ожидается
  • Bash в примерах, Часть 2: Ещё больше об основах программирования в bash — на английском, ждите перевода
  • Bash в примерах, Часть 3: Рассматриваем систему ebuild-ов — на английском, перевод будет
Продолжение...



Об авторах


Daniel Robbins


Дэниэль Роббинс — основатель сообщества Gentoo и создатель операционной системы Gentoo Linux. Дэниэль проживает в Нью-Мехико со свой женой Мэри и двумя энергичными дочерьми. Он также основатель и глава Funtoo, написал множество технических статей для IBM developerWorks, Intel Developer Services и C/C++ Users Journal.



Chris Houser


Крис Хаусер был сторонником UNIX c 1994 года, когда присоединился к команде администраторов университета Тэйлора (Индиана, США), где получил степень бакалавра в компьютерных науках и математике. После он работал во множестве областей, включая веб-приложения, редактирование видео, драйвера для UNIX и криптографическую защиту. В настоящий момент работает в Sentry Data Systems. Крис также сделал вклад во множество свободных проектов, таких как Gentoo Linux и Clojure, стал соавтором книги The Joy of Clojure.



Aron Griffis


Эйрон Гриффис живет на территории Бостона, где провел последнее десятилетие работая в Hewlett-Packard над такими проектами, как сетевые UNIX-драйвера для Tru64, сертификация безопасности Linux, Xen и KVM виртуализация, и самое последнее — платформа HP ePrint. В свободное от программирования время Эйрон предпочитает размыщлять над проблемами программирования катаясь на своем велосипеде, жонглируя битами, или болея за бостонскую профессиональную бейсбольную команду «Красные Носки».

Share post

Similar posts

Comments 54

    +4
    Спасибо за очередную порцию отличного перевода отличного учебного пособия!
      +1
      Кстати, интересный момент, если в каталоге очень много файлов, то шаблон * разворачивается в слишком длинную строку, и скажем когда надо все эти файлы грохнуть, команда типа rm * вам скажет, что список аргументов слишком длинный. И очистить такой каталог получится только весьма нетривиальным способом.
        0
        for i in *;rm $i

        достаточно нетривиально?
          0
          я обычно find. -exec rm {} \;

          кстати только что попробовал через mc: «выделить все», F8, ентер.
          в бешенстве рвал волосы отовсюду.
            0
            Вы специально недоговариваете, что при этом произошло, чтобы мы тоже попробовали? ;)
              0
              автор видимо стал полностью лысым)

              я обычно тоже папки удаляю mc, f8, enter
              0
              find . -delete
            0
            ls |xargs rm -f
            0
            ммм… а конструкция вида `rm {file1,file2,file3,file4}` не относится сюда?
              0
              Нет, тут задействуется несколько иной механзм. Можете проверить, хотя бы то, что преобразование произойдет даже если полученый результат не существует в файловой системе.
              –3
              «Джокер»? Статья о покере?
                –1
                Джокер используется не только в покере, но во многих других карточных играх, а также, например, в моджонге, где представляет из себя фишку. Очевидно, метод работы специальных символов, описываемых в статье, очень похож на использование данной карты в играх. Поэтому не спроста они получили такое название. Вы можете предложить более качественный и емкий короткий перевод для «wild card»?
                  0
                  Маска. Существует еще с тех пор, когда еще я в школу ходил и терся на местном железнодорожном ВЦ.
                    –1
                    Я не знаю, что там в железнодорожном ВЦ. Мягко говоря не авторитетный для меня источник. =) Последние несколько лет читаю документацию и техническую литературу только на английском, даже при наличии перевода. На русском же, то что мне попадалось, как правило полная бестолковщина в терминалогии. Маской зовется весь заданный шаблон поиска целиком, состоящий из различных метасимволов, а отдельные символы в нем как раз будут: ru.wikipedia.org/wiki/Символыджокеры иначе и не переведешь. И то, маской шаблон можно назвать только в том случае, если шаблон по принципу действия является маскирующим, а не наоборот, трафаретно-подстановочным.
                      –1
                      Хабропарсер скушал http://ru.wikipedia.org/wiki/Символы-джокеры. Википедия, конечно, тоже не особо авторитетный источник, но приписывать мне изобретение оригинального перевода для wild cards не надо.
                        –1
                        Ох, да вы оказывается не единственный, но извините, это же все меняет ;-)
                        0
                        М, то есть если вы разучились говорить на русском, то можете придумывать мокроступы? Оригинальная позиция. А может все таки напрячься, и придумать человеческое название? Пока джокеры у вас у одного во всей России.
                          –1
                          Из всех возможных вариаций переводов wild card — джокер самое близкое по смыслу. Будете спорить? Давайте тогда поговорим о разнице между маской и шаблоном. И о том, что например метасимвол не всегда является при этом wild card. Благодаря тому, что я ни читаю русских доков, у меня нет каши в голове.
                            0
                            Заносит вас. Может помимо доки надо там литературки читнуть? Для любви к родному, великому и могучему. Может тогда не будете тянуть чужеродные коннотации? Я же поясняю — у нас нет специального такого значения у «джокера». Джокер для обычного человека это просто карта, из неиграбельной колоды в 52 штуки, из которой половину выкидывать приходится.
                              0
                              Если так рассуждать, то для обычного человека маска — это то, что на голову надевают. А шаблон — это то, что заполнять надо. Что для обычного человека оболочка, или приветствие интепретатора — даже подумать страшно. Я не играю в карточные игры, и для меня джокер — это карта, которая может прикидываться любой другой картой. Сдается мне, не я один такой. И если мне сказать, что джокеры это символы с похожими свойствами, будет вполне понятно.

                              Спор бессмысленный. Вам не нравится перевод — делайте свой, и сможете переводить термины, как вы привыкли, как вам захочется, основываясь на своем представлении об устройстве вселенной и литературном опыте. Хотите бескомпромиссной точности — читайте оригинал, чем я, например, всегда и занимаюсь.
                                +1
                                Джокер для обычного человека это просто карта, из неиграбельной колоды в 52 штуки
                                Опять не угадали. Полная колода с джокерами — 54 листа.
                                  –1
                                  Я же объяснил — мне пофиг сколько там листов ;) Не играю я в карточные игры.
                            –1
                            Железнодорожные ВЦ, шоб вы знали, центр инженерной мысли того времени. Там было и оборудование и инженеры.
                              0
                              Хорошо, вот часто используемый вариант — «символы подстановки».

                              А «джокер» просто вырубает — ну не означает он у нас некую субстанцию, которой можно что угодно подменить.
                                –1
                                «символы подстановки» — более менее адекватный вариант ИМХО, но замените джокеры на символы подстановки, не забыв просклонять это выражение, и получите чуть менее читабельный вариант статьи.
                                  0
                                  Ладно, мне пофиг, хабр в любом случае не сборник образцовых творений: ) И джокера вашего он тоже переживет.
                          +2
                          > «Джокер»? Статья о покере?

                          Да вы, я посмотрю, знаток покера.
                          К вашему сведению, в наиболее распространённых видах покера карта Джокер не используется.
                            0
                            Да мне безразличны карточные игры, просто «джокер» никогда в жизни не применялся в русском в качестве перевода wild card.
                          0
                          ls /etc/[0-9]* покажет все файлы в /etc, начинающиеся с числа;
                          Не с числа, а с десятичной цифры.
                            0
                            11x, начинается с числа, но под шаблон подходит
                              0
                              Разумеется, когда переводил я как раз об этом подумал, и позволил себе чуть более вольный перевод. Но будем придерживаться строгости, все-таки статья для новичков.
                                0
                                т.е. с цифры 1 оно не начинается?
                                  0
                                  и с цифры 1 тоже начинается. все зависит от того, как на это посмотреть
                                    0
                                    Все же xn__p2a прав. Числа могут быть отрицательными, дробными, мнимыми, да много еще какими.
                                      0
                                      И, например, отрицательное число не начинается с цифры…
                                        0
                                        да, действительно :)
                                  0
                                  Спасибо за уточнение. В голове крутилось «номер» и «число», а слово «цифра» не смог вспомнить. =)
                                    0
                                    Десятичная цифра — и есть число. А вот число — не есть десятичная цифра.
                                    таким образом, автор употребил более ёмкое понятие «число».
                                    Хотя в данной ситуации верны оба утверждения. Спорить бессмысленно.
                                      0
                                      строго говоря, цифра — не число, также как буква — не слово, это элементы алафавита из которых составляются слова
                                    0
                                    На самом деле не сказал бы что тема раскрыта очень хорошо. IMO более наглядно и доходчиво описано тут
                                      0
                                      почему дикая кошка то? wildcard же
                                        0
                                        Там где переведено «дикая кошка» в оригинале использовалось wildcat.
                                          +1
                                          Я тоже про кошку не понял.
                                          Я бы перевёл на русский слово wildcard как «маска», «подстановка» или «шаблон».
                                          И соответственно «wildcard name» как «имя по маске», «имя с подстановкой», «подстановочное имя», «имя по шаблону» и т.п.
                                            –1
                                            Wild card везде переведено как джокер. Шаблон в переводе тоже присутсвует, и это все-таки pattern, имеет другой смысл. Подстановка это таки substitution, и больше относится к контексту операций с переменными. В каждой статье существует определенный набор терминов, и переводчику необходимо определиться с их однозначным переводом, и его придерживаться, если вы переведете wild card как шаблон, то потом, вам придется придумывать перевод для pattern и т. п., вы рискуете получить путаницу. Упомянутое вами wildcard name вообще нигде такого сочетания не встричается. Непонятно, даже что вы имели под этим ввиду, что за выражение такое?

                                            Более адекватного перевода для wildcat, чем дикая кошка, найти не смог.
                                              0
                                              Может это опечатка у автора и имелось ввиду wildcard? Где-то еще есть источники с таким термином? Гугл ничего подобного мне не нашёл.

                                              Кстати и перевод «джокер» первый раз встречаю. Однозначного перевода нет, но чаще «маска» или «шаблон». Хотя на смысл это не влияет.
                                                0
                                                Не похоже на опечатку, тем более сразу в нескольких местах, и явно выделено курсивом, как какой-то специальный терми «wildcat pattern».

                                                Да и если погуглить, к примеру, вот: http://www.mail-archive.com/beginners@perl.org/msg43913.html
                                                  0
                                                  2 раза всего и очень много раза wild card и у обоих есть похожие значения, поэтому англоязычные люди вполне могут иногда допускать такие ошибки.

                                                    0
                                                    (нажал какую-то волшебную клавишу для отправки рано)
                                                    wild card — непредсказуемый человек
                                                    wildcat — необузданный человек
                                                      0
                                                      Ок. Я поинтересуюсь у Дэниэля, ошибка ли это.
                                                        0
                                                        Мне он ответил, что это существующий термин, который редко используется, поэтому, возможно, он заменит его в статье на «wildcard».
                                                  –1
                                                  Ничего более адекватного, чем перевести дословно ;-)
                                              0
                                              У меня у одного возник вопрос, что такое «man 8 glob» раздел QUOTING? Очевидно, автор имел в виду «man 1 bash».
                                                0
                                                Спасибо за замечание, поправил.
                                                0
                                                Молодец, полезные статьи!

                                                Only users with full accounts can post comments. Log in, please.