==
Operator służy do porównywania dwóch ciągów w skorupkach skryptu. Jednak chcę porównać dwa ciągi, ignorując wielkość liter, jak to zrobić? Czy jest do tego jakieś standardowe polecenie?
string
shell
compare
case-insensitive
Sachin Chourasiya
źródło
źródło
if
instrukcji,shopt
podejście to wymaga użycia[[ ]]
formy warunkowej z podwójnym nawiasem zamiast postaci z pojedynczym nawiasem[ ]
. Zobacz też: gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html==
jest używane do porównywania dwóch ciągów, ale odpowiedź demonstruje porównanie bez rozróżniania wielkości liter przy użyciucase
instrukcji. Uspokajająco Theshopt
rozwiązanie umożliwia również bez uwzględniania wielkości liter wykorzystania==
,=~
oraz innych operatorów porównania ciąg.shopt -u nocasematch
po wykonaniu porównania, aby powrócić do domyślnych ustawień basha.nocasematch
ustawienie. Chwyć go, aSHELLNOCASEMATCH=`shopt -p nocasematch`
następnie zmień za pomocą,shopt -s nocasematch
a po$SHELLNOCASEMATCH
SHELLNOCASEMATCH=$(shopt -p nocasematch; true)
ponieważshopt -p
zakończy pracę z kodem 1, jeśli opcja nie jest ustawiona, a to może spowodować przerwanie działania skryptu, jeśliset -e
jest aktywny.W Bash możesz użyć interpretacji parametrów, aby zmodyfikować ciąg znaków na małe / duże litery:
var1=TesT var2=tEst echo ${var1,,} ${var2,,} echo ${var1^^} ${var2^^}
źródło
echo
stwierdzenie skutkuje:-bash: ${var1,,}: bad substitution
shopt -s nocasematch
jest zaimplementowany, ale zazwyczaj takie rozwiązania "językowe" radzą sobie z tym poprawnie.,,
i^^
pracują,bash 4.4.20
ale żadne nie pracujązsh 5.4.2
(ubuntu 18.04)Wszystkie te odpowiedzi ignorują najłatwiejszy i najszybszy sposób na zrobienie tego (o ile masz Bash 4):
if [ "${var1,,}" = "${var2,,}" ]; then echo ":)" fi
Wszystko, co tam robisz, to konwertowanie obu ciągów na małe litery i porównywanie wyników.
źródło
Zapisz stan nocasematch (w przypadku, gdy inna funkcja zależy od jej wyłączenia):
local orig_nocasematch=$(shopt -p nocasematch) shopt -s nocasematch [[ "foo" == "Foo" ]] && echo "match" || echo "notmatch" $orig_nocasematch
Uwaga: używaj tylko
local
wtedy, gdy znajduje się wewnątrz funkcji.źródło
case
stwierdzenia (w tym te w odpowiedzi Ghostdog) zawsze sprawią, że moja skóra zacznie pełzaćJednym ze sposobów byłoby przekonwertowanie obu ciągów na wyższy lub niższy:
test $(echo "string" | /bin/tr '[:upper:]' '[:lower:]') = $(echo "String" | /bin/tr '[:upper:]' '[:lower:]') && echo same || echo different
Innym sposobem byłoby użycie grep:
echo "string" | grep -qi '^String$' && echo same || echo different
źródło
tr
metody w moich dokerizowanych aplikacjach opartych na alpine (który dostarczash
viabusybox
). Dziękuję Ci.W przypadku powłoki Korn używam wbudowanego polecenia typeset (-l dla małych liter i -u dla dużych).
var=True typeset -l var if [[ $var == "true" ]]; then print "match" fi
źródło
Bardzo proste, jeśli fgrep zrobisz porównanie linii bez rozróżniania wielkości liter:
str1="MATCH" str2="match" if [[ $(fgrep -ix $str1 <<< $str2) ]]; then echo "case-insensitive match"; fi
źródło
if fgrep -qix -- "$str1" <<<"$str2"; then
zamiast tego.Oto moje rozwiązanie wykorzystujące 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
źródło
grep
ma-i
flagę, która oznacza, że wielkość liter nie jest rozróżniana, więc poproś o informację, czy zmienna2 jest w zmiennej1.var1=match var2=MATCH if echo $var1 | grep -i "^${var2}$" > /dev/null ; then echo "MATCH" fi
źródło
Ponieważ
zsh
składnia jest nieco inna, ale nadal krótsza niż większość odpowiedzi tutaj:> str1='mAtCh' > str2='MaTcH' > [[ "$str1:u" = "$str2:u" ]] && echo 'Strings Match!' Strings Match! >
Spowoduje to konwersję obu ciągów na wielkie litery przed porównaniem.
Inna metoda wykorzystuje zsh
globbing flags
, co pozwala nam bezpośrednio korzystać z dopasowywania bez uwzględniania wielkości liter za pomocąi
flagi glob:setopt extendedglob [[ $str1 = (#i)$str2 ]] && echo "Match success" [[ $str1 = (#i)match ]] && echo "Match success"
źródło
Natknąłem się na ten świetny blog / samouczek / cokolwiek o radzeniu sobie z wzorcem uwzględniającym wielkość liter . Poniższe trzy metody są szczegółowo wyjaśnione z przykładami:
1. Przekonwertuj wzór na małe litery za pomocą polecenia tr
opt=$( tr '[:upper:]' '[:lower:]' <<<"$1" ) case $opt in sql) echo "Running mysql backup using mysqldump tool..." ;; sync) echo "Running backup using rsync tool..." ;; tar) echo "Running tape backup using tar tool..." ;; *) echo "Other options" ;; esac
2. Używaj ostrożnego globowania z wzorami wielkości liter
opt=$1 case $opt in [Ss][Qq][Ll]) echo "Running mysql backup using mysqldump tool..." ;; [Ss][Yy][Nn][Cc]) echo "Running backup using rsync tool..." ;; [Tt][Aa][Rr]) echo "Running tape backup using tar tool..." ;; *) echo "Other option" ;; esac
3. Włącz nocasematch
opt=$1 shopt -s nocasematch case $opt in sql) echo "Running mysql backup using mysqldump tool..." ;; sync) echo "Running backup using rsync tool..." ;; tar) echo "Running tape backup using tar tool..." ;; *) echo "Other option" ;; esac shopt -u nocasematch
źródło
shopt -s nocaseglob
źródło