Сравнение строк без учета регистра в сценарии оболочки

== Оператор используется для сравнения двух строк в сценарии оболочки. Тем не менее, я хочу сравнить две строки без учета регистра, как это можно сделать? Есть ли стандартная команда для этого?

Ответы на вопрос(10)

Решение Вопроса

если у вас есть Баш

str1="MATCH"
str2="match"
shopt -s nocasematch
case "$str1" in
 $str2 ) echo "match";;
 *) echo "no match";;
esac

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

альтернатива, используя awk

str1="MATCH"
str2="match"
awk -vs1="$str1" -vs2="$str2" 'BEGIN {
  if ( tolower(s1) == tolower(s2) ){
    print "match"
  }
}'
 jnylen22 авг. 2018 г., 05:51
Еще лучше:SHELLNOCASEMATCH=$(shopt -p nocasematch; true), так какshopt -p выйдет с кодом 1, если опция не установлена, и это может привести к прерыванию работы скрипта, еслиset -e в силе.
 Urhixidur05 дек. 2017 г., 20:25
Лучше всего сохранить и восстановитьnocasematch установка. Возьми это сSHELLNOCASEMATCH=`shopt -p nocasematch` затем измените его сshopt -s nocasematch и после этого восстановите его$SHELLNOCASEMATCH
 Ohad Schneider12 янв. 2017 г., 17:44
Вероятно, разумно выполнитьshopt -u nocasematch после сравнения, чтобы вернуться к Bash 'по умолчанию.
 indiv28 сент. 2012 г., 00:37
Для тех, кто сравнивает строки, используяif заявления,shopt подход требует, чтобы вы использовали двойную скобку[[ ]] условная форма вместо одинарной скобки[ ] форма. Смотрите также:gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html
 taranaki01 дек. 2015 г., 03:35
Вопрос указывает на то, что== используется для сравнения двух строк, но ответ демонстрирует сравнение без учета регистра с использованиемcase заявление. Успокаивающеshopt Решение также позволяет без учета регистра использовать===~и другие операторы сравнения строк.

ных букв и -u для прописных).

var=True
typeset -l var
if [[ $var == "true" ]]; then
    print "match"
fi
 Bharat15 сент. 2018 г., 15:04
В bash для установки атрибутов можно использовать декларацию -l или -u.
 Alex12 дек. 2013 г., 15:38
Это намного лучше с точки зрения производительности, чем запуск awk или любого другого процесса.
var1=match 
var2=MATCH 
if echo $var1 | grep -i "^${var2}$" > /dev/null ; then
  echo "MATCH"
fi
 haridsv11 февр. 2013 г., 12:16
победил'не работает, если в var2 есть специальные символы регулярного выражения.
 Arash Milani24 дек. 2012 г., 03:24
добро пожаловать в stackoverflow. Вы можете добавить описание того, как это работает для будущих посетителей этого вопроса.
 jww24 июн. 2016 г., 00:59
Умный ответ ...

Заzsh синтаксис немного отличается:

> str1='MATCH'
> str2='match'
> [ "$str1" == "$str2:u" ] && echo 'Match!'
Match!
>

Это преобразуетstr2 в верхнем регистре перед сравнением.

Больше примеров для изменения регистра ниже:

> xx=Test
> echo $xx:u
TEST
> echo $xx:l
test

test $(echo "string" | /bin/tr '[:upper:]' '[:lower:]') = $(echo "String" | /bin/tr '[:upper:]' '[:lower:]') && echo same || echo different

Другой способ - использовать grep:

echo "string" | grep -qi '^String && echo same || echo different

чтобы изменить строку для всех строчных и прописных букв:

var1=TesT
var2=tEst

echo ${var1,,} ${var2,,}
echo ${var1^^} ${var2^^}
 Ohad Schneider12 янв. 2017 г., 17:41
Такие реализации сравнения без учета регистра склонны к проблемам локализации (например, проблема турецкого языка I). Я нене знаю какshopt -s nocasematch но обычно такое "языка на уровне» решения справляются с этим правильно.
 Jason Carter01 июн. 2019 г., 15:51
пользователи MacOS, обновите версию Bash. К этому моменту ваша история устарела более чем на десять лет.itnext.io/upgrading-bash-on-macos-7138bd1066ba
 Starlton10 мая 2019 г., 23:44
./anothertest.sh: строка 4: $ {var1 ,,}: неправильная замена ./anothertest.sh: строка 5: $ {var1 ^^}: неправильная замена
 jehon02 мар. 2014 г., 07:30
По крайней мере, ответ, который не подразумевает выбранный вариант. Таким образом, вы можете сравнить две строки, игнорируя регистр, и в том же тесте сравнить две другие с регистром. Спасибо
 Ben Leggiero18 февр. 2019 г., 17:25
м с @FelixRabe; на macOS 10.13.6, которая поставляется с Bash 3.2.57 и выдает ту же ошибку
 Felix Rabe11 июн. 2014 г., 15:33
Это новое в Bash 4? По крайней мере, в Bash 3.2.51 (используется в OS X 10.9) это не работает - первыйecho Результаты заявления в:-bash: ${var1,,}: bad substitution
 iloveretards15 авг. 2017 г., 19:59
@ Охад Шнайдер, позвольте туркам беспокоиться о проблемах турецкой локализации, мне просто нужен быстрый и эффективный способ сопоставления строк, и это делает пирог маркой huuuuuge marginI '

если у вас есть Bash 4):

if [ "${var1,,}" = "${var2,,}" ]; then
  echo ":)"
fi

Все вы'здесь выполняется преобразование обеих строк в нижний регистр и сравнение результатов.

 d4Rk11 мая 2016 г., 16:47
Это доступно только в Bash 4 или новее (например, не в Mac OS X 10.11)
 d4Rk12 мая 2016 г., 08:38
@ Очень жаль, не так лиВо-первых, не замечаю этого. Я знаю, что вы можете установить любой bash на OS X, но по умолчанию используется 3.2, и, поскольку мой скрипт должен работать и на разных компьютерах Mac, это не совсем вариант для меня.
 Riot12 мая 2016 г., 02:24
@ d4Rk, поэтому первое предложение моего ответа гласит:пока у вас есть Bash 4 ", Тем не менее, на момент написания этого комментария Bash 4 отсутствовал более семи лет, и моя собственная установка OS X имела его почти так долго.
 Riot12 мая 2016 г., 14:52
@ d4Rk это 'Понятно - если вам действительно нужно гарантировать переносимость, я бы предложил придерживаться стандарта оболочки POSIX, так как выВ некоторых случаях не гарантируется вообще найти какую-либо версию bash.
 Robin Winslow20 февр. 2019 г., 13:53
Это именно то, что я искал. Должно быть выше =)

если вы воспользуетесь fgrep, чтобы сделать строку без учета регистра:

str1="MATCH"
str2="match"

if [[ $(fgrep -ix $str1 <<< $str2) ]]; then
    echo "case-insensitive match";
fi
 Doogle10 окт. 2018 г., 11:54
Да, похоже, работает с grep и egrep
 jww24 июн. 2016 г., 01:00
Это работает дляgrep а такжеegrep, тоже?

Вот мое решение с использованием tr:

var1=match
var2=MATCH
var1=`echo $var1 | tr '[A-Z]' '[a-z]'`
var2=`echo $var2 | tr '[A-Z]' '[a-z]'`
if [ "$var1" = "$var2" ] ; then
  echo "MATCH"
fi

что и ответ от ghostdog74, но немного другой код

shopt -s nocasematch
[[ "foo" == "Foo" ]] && echo "match" || echo "notmatch"
shopt -u nocasematch
 SeldomNeedy28 июл. 2015 г., 21:43
Хорошо, потому чтоcase заявления (в том числе в Ghostdog 'ответ) всегда заставит мою кожу ползти

Ваш ответ на вопрос