==
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?
==
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?
Odpowiedzi:
jeśli masz bash
str1="MATCH"
str2="match"
shopt -s nocasematch
case "$str1" in
$str2 ) echo "match";;
*) echo "no match";;
esac
w przeciwnym razie powiedz nam, jakiej powłoki używasz.
alternatywa, używając awk
str1="MATCH"
str2="match"
awk -vs1="$str1" -vs2="$str2" 'BEGIN {
if ( tolower(s1) == tolower(s2) ){
print "match"
}
}'
==
jest używane do porównywania dwóch ciągów, ale odpowiedź demonstruje porównanie bez rozróżniania wielkości liter przy użyciu case
instrukcji. Uspokajająco The shopt
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, a SHELLNOCASEMATCH=`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śli set -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^^}
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.
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.
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
tr
metody w moich dokerizowanych aplikacjach opartych na alpine (który dostarcza sh
via busybox
). 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
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
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
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
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"
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
shopt -s nocaseglob
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