Операторы сопоставления с шаблоном позволяют найти в переменной некоторый шаблон и, если этот этот шаблон найден, изменить переменную. Это следующие операторы:
Оператор ## используется для поиска самого длинного соответствия шаблону с начала строки
Оператор # используется для поиска самого короткого соответствия шаблону с начала строки
Оператор %% используется для поиска самого длинного соответствия шаблону с конца строки
Оператор % используется для поиска самого короткого соответствия шаблону с конца строки
Например, определим в домашнем каталоге следующий скрипт hello:
#!/bin/bash # скрипт, который получает имя файла filename=${1##*/} echo "The filename is $filename" exit 0
В данном случае поиск шаблона применяется к идентификатору $1 - первому аргмуенту, который передается скрипту из командной строки. К этому аргументу применяется оператор ##, который ищет сооответствие в строке шаблона "*/". То есть оператор ищет /, которому предшествует любой другой символ (*). Так как оператор ## ищет самое длинное соответствие, то фактически он ищет последний /, который встречается в строке, и удаляет его, а также все, что предшествует /. То есть по сути из пути к файлу мы получим имя файла.
Запустим данные скрипт и передадим ему полный путь путь к какому-нибудь файлу:
eugene@Eugene:~$ bash hello /home/eugene/Documents/hello.txt The filename is hello.txt eugene@Eugene:~$
Используя оператор #, можно найти самое короткое соответствие. Например, изменим скрипт следующим образом:
#!/bin/bash # скрипт, который получает имя файла path=${1#*/} echo "path: $path" exit 0
Запустим скрипт, передав ему путь к файлу:
eugene@Eugene:~$ bash hello /home/eugene/Documents/hello.txt path: home/eugene/Documents/hello.txt eugene@Eugene:~$
В данном случае оператор будет искать первый символ / в полном имени файла и удалять его и все, что находится перед ним. Вы должны понимать, что в этих примерах важен знак *.
Оператор ${1#*/}
удаляет первый найденный символ / и все, что находится перед ним. Оператор ${1#/}
удаляет первый символ / в $1,
только если значение $1 начинается с символа /. Однако если перед / есть что-то, оператор не будет знать, что делать.
Или другой пример, получим относительный путь к файлу:
#!/bin/bash # скрипт, который получает относительный путь к файлу rel_path=${1#$PWD/} echo "Relative path: $rel_path" exit 0
Здесь искомый шаблон устанавливается на основе переменной $PWD и символа /. Запустим скрипт и передадим ему полный абсолютный путь к файлу:
eugene@Eugene:~$ echo $PWD /home/eugene eugene@Eugene:~$ bash hello /home/eugene/Documents/hello.txt Relative path: Documents/hello.txt eugene@Eugene:~$
Операторы %% и % в целом аналогичны, только ищут соответствие с конца строки. Например, изменим скрипт следующим образом:
#!/bin/bash # скрипт, который получает каталог файла dirname=${1%/*} echo "Directory: $dirname" exit 0
В данном случае оператор ${1%/*}
ищет первый слеш с конца (или последний слеш с начала), после которого стоит произвольный символ. И все та часть строки, которая идет начиная с этого слеша обрезается. То есть фактически мы получим каталог файла.
Запустим скрипт и передадим ему полный путь к какому-нибудь файлу:
eugene@Eugene:~$ bash hello /home/eugene/Documents/hello.txt Directory: /home/eugene/Documents eugene@Eugene:~$