Регистронезависимое сравнение строк в Bash

 

 Bashсниппет

Сравнение строк в Bash не вызывает никаких проблем до тех пор, пока не возникает задача сравнить две строки, не учитывая регистр символов. Я приведу несколько вариантов решения задачи, которые использую сам. Особенностью этих решений является использование только встроенных возможностей оболочки Bash.

Для начала я создам две переменные str1 и str2, содержащие строки, подлежащие сравнению. Именно они будут использоваться в следующих примерах кода.

#!/bin/bash

str1='String To Compare'
str2='string to compare'

В первом варианте регистронезависимого сравнения строк, который я хочу предложить, используется управление опциями оболочки при помощи встроенной команды shopt.

shopt -s nocasematch
[[ $str1 == $str2 ]] && echo 'match' || echo 'not match'
shopt -u nocasematch

Следующий вариант регистронезависимого сравнения строк основывается на принципе самостоятельного приведения строк к общему регистру. Этот вариант кода работает на версии Bash 4 и новее. Использование его на более ранней версии Bash приведёт к возникновению ошибки.

Так, для сравнения строк, приведённых к нижнему регистру, можно использовать следующий вариант кода.

[[ "${str1,,}" == "${str2,,}" ]] && echo 'match' || echo 'not match'

Если вы хотите привести сравниваемые строки к верхнему регистру, то можно использовать следующий код.

[[ "${str1^^}" == "${str2^^}" ]] && echo 'match' || echo 'not match'

В качестве альтернативного варианта, приведение строк к единому регистру может быть выполнено в момент декларирования переменных. Для этого используется встроенная команда оболочки declare.

Для того, чтобы декларировать переменную, содержащую текст в нижнем регистре, используется следующий код.

#!/bin/bash

declare -l str='Camel Case String'

В результате выполнения этого кода, в переменной str будет содержаться строка в нижнем регистре, не смотря на то, что присваиваемая строка была записана в camel case. Изменить регистр уже заданной в переменной строки можно следующим образом.

#!/bin/bash

str='Camel Case String'
declare -l str
str=$str

echo $str

Для приведения строки к верхнему регистру, в приведённом примере кода следует изменить вызов команды declare, используя вместо ключа -l ключ -u.

Теперь регистронезависимое сравнение строк с использование команды declare может быть выполнено следующим образом.

declare -l str1_l=$str1
declare -l str2_l=$str2

[[ $str1_l == $str2_l ]] && echo 'match' || echo 'not match'

Любой из рассмотренных вариантов регистронезависимого сравнения строк может быть использован при написании сценариев Bash. Поэтому, если используете версию Bash 4 и выше, можете выбирать тот, который понравился вам больше. Если же версия Bash ниже 4, то следует использовать первый вариант с заданием опции nocasematch при помощи встроенной команды оболочки shopt.