Pattern matching

Последнее обновление: 23.03.2024

Операторы сопоставления с шаблоном позволяют найти в переменной некоторый шаблон и, если этот этот шаблон найден, изменить переменную. Это следующие операторы:

  • Оператор ## используется для поиска самого длинного соответствия шаблону с начала строки

  • Оператор # используется для поиска самого короткого соответствия шаблону с начала строки

  • Оператор %% используется для поиска самого длинного соответствия шаблону с конца строки

  • Оператор % используется для поиска самого короткого соответствия шаблону с конца строки

Например, определим в домашнем каталоге следующий скрипт 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:~$ 
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850