Kabuk betiğindeki dizelerin büyük / küçük harf duyarlı karşılaştırması


129

==Operatör kabuk komut iki dizeleri için kullanılır. Ancak iki dizgeyi büyük / küçük harfleri görmezden gelerek karşılaştırmak istiyorum, nasıl yapılabilir? Bunun için herhangi bir standart komut var mı?

Yanıtlar:


72

bash varsa

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

aksi takdirde, bize hangi kabuğu kullandığınızı söylemelisiniz.

alternatif, awk kullanarak

str1="MATCH"
str2="match"
awk -vs1="$str1" -vs2="$str2" 'BEGIN {
  if ( tolower(s1) == tolower(s2) ){
    print "match"
  }
}'

32
ifİfadeleri kullanarak dizeleri karşılaştıran herkes için bu shoptyaklaşım [[ ]], tek köşeli parantez yerine çift ​​köşeli parantez koşullu formun kullanılmasını gerektirir [ ]. Ayrıca bkz .: gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html
indiv

3
Soru, ==iki dizeyi karşılaştırmak için kullanıldığını gösterir , ancak yanıt, bir caseifade kullanarak büyük / küçük harfe duyarlı olmayan karşılaştırmayı gösterir . Reassuringly, shoptçözüm ayrıca küçük harfe duyarsız kullanımını sağlayan ==, =~ve diğer dize karşılaştırma operatörlerini.
taranaki

7
Muhtemelen shopt -u nocasematchkarşılaştırma yapıldıktan sonra bash'ın varsayılanına geri dönmek için yürütmek akıllıca olacaktır .
Ohad Schneider

6
nocasematchAyarı kaydetmek ve geri yüklemek için en iyisi . İle Kepçe SHELLNOCASEMATCH=`shopt -p nocasematch`sonra bunu değiştirmek shopt -s nocasematchve bitmiş bir kez ile geri$SHELLNOCASEMATCH
Urhixidur

2
Daha da iyisi: SHELLNOCASEMATCH=$(shopt -p nocasematch; true)çünkü shopt -pseçenek ayarlanmadıysa kod 1 ile çıkılır ve bu etkinse komut dosyasının iptal edilmesine neden olabilir set -e.
We Are All Monica

159

Bash'de, bir dizeyi tümü küçük / büyük harf olacak şekilde değiştirmek için parametre genişletmeyi kullanabilirsiniz:

var1=TesT
var2=tEst

echo ${var1,,} ${var2,,}
echo ${var1^^} ${var2^^}

14
En azından alışveriş seçeneğini ima etmeyen bir cevap. Böylece iki dizeyi durumu yok sayarak karşılaştırabilir ve aynı testte diğer ikisini büyük / küçük harf ile karşılaştırabilirsiniz. Teşekkürler
jehon

38
Bu Bash 4'te yeni mi? En azından Bash 3.2.51'de (OS X 10.9'da kullanılır) çalışmıyor - ilk echoifade şu sonuca varıyor :-bash: ${var1,,}: bad substitution
Felix Rabe

1
Bu tür duruma duyarsız karşılaştırma uygulamaları yerelleştirme sorunlarına eğilimlidir (Türk I sorunu gibi). Nasıl shopt -s nocasematchuygulandığını bilmiyorum ama genellikle bu tür "dil düzeyinde" çözümler bunu doğru bir şekilde ele alıyor.
Ohad Schneider

5
@Ohad Schneider, Türklerin Türk yerelleştirme sorunları konusunda endişelenmesine izin verin, sadece hızlı ve verimli bir dizgi eşleştirme yöntemine ihtiyacım var ve bu da pastayı çok büyük bir marjla alıyor
niken

1
macOS kullanıcıları, Bash sürümünüzü yükseltin. Sizinki bu noktada on yıldan fazla bir süredir güncel değil. itnext.io/upgrading-bash-on-macos-7138bd1066ba
Jason Carter

116

Tüm bu yanıtlar, bunu yapmanın en kolay ve en hızlı yolunu görmezden gelir (Bash 4'e sahip olduğunuz sürece):

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

Orada yaptığınız tek şey, her iki dizeyi de küçük harfe dönüştürmek ve sonuçları karşılaştırmaktır.


6
Bu yalnızca Bash 4 veya daha yeni sürümlerde mevcuttur (örneğin, Mac OS X
10.11'de

8
@ d4Rk bu yüzden cevabımın ilk cümlesi "Bash 4'e sahip olduğunuz sürece" diyor. Bunu söyledikten sonra, Bash 4 bu yorumu yazarken yedi yıldan fazla bir süredir piyasadaydı ve kendi OS X kurulumumda neredeyse o kadar uzun süredir var.
Riot

@Riot üzgünüm, bunu ilk etapta fark etmedim. OS X'e istediğiniz bash'ı yükleyebileceğinizi biliyorum, ancak varsayılan 3.2'dir ve betiğim farklı Mac'lerde de çalışmalıdır, bu benim için pek bir seçenek değil.
d4Rk

2
@ d4Rk bu anlaşılabilir bir durum - gerçekten taşınabilirliği garanti etmeniz gerekiyorsa, bazı durumlarda bash'nin herhangi bir sürümünü bulmanız garanti edilmediğinden, POSIX kabuk standardına bağlı kalmanızı öneririm.
Riot

1
Bu tam olarak aradığım şeydi. Daha yüksek olmalı =)
Robin Winslow

39

Nocasematch durumunu kaydedin (başka bir işlevin devre dışı bırakılmasına bağlı olması durumunda):

local orig_nocasematch=$(shopt -p nocasematch)
shopt -s nocasematch
[[ "foo" == "Foo" ]] && echo "match" || echo "notmatch"
$orig_nocasematch

Not: yalnızca localbir işlevin içindeyse kullanın .


4
Güzel çünkü caseifadeler (hayalet köpeğin cevabındakiler dahil) her zaman
cildimi

15

Bunun bir yolu, her iki dizeyi de yukarı veya aşağıya dönüştürmek olabilir:

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

Başka bir yol da grep kullanmaktır:

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

Kullandığım tr(içerir alpine göre zaman docker-ize uygulamalarda yöntem shile busybox). Teşekkür ederim.
MXWest

7

Korn kabuğu için, dizgi yerleşik komutunu kullanıyorum (küçük harf için -l ve büyük harf için -u).

var=True
typeset -l var
if [[ $var == "true" ]]; then
    print "match"
fi

2
Bu, performans açısından awk veya başka herhangi bir işlemi başlatmaktan çok daha iyidir.
Alex

1
Bash'de, -l veya -u bildirmek öznitelikleri ayarlamak için kullanılabilir.
Bharat

6

Büyük / küçük harfe duyarlı olmayan bir satır karşılaştırması yapmaya karar verirseniz çok kolaydır:

str1="MATCH"
str2="match"

if [[ $(fgrep -ix $str1 <<< $str2) ]]; then
    echo "case-insensitive match";
fi

Bunun if fgrep -qix -- "$str1" <<<"$str2"; thenyerine kullanmak daha iyi olur .

3

İşte benim tr kullanarak çözümüm:

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

3

grepbüyük / -iküçük harfe duyarlı olmayan bir bayrağa sahiptir, bu nedenle var2'nin var1'de olup olmadığını size söylemesini isteyin.

var1=match 
var2=MATCH 
if echo $var1 | grep -i "^${var2}$" > /dev/null ; then
    echo "MATCH"
fi

3
var2'de herhangi bir normal ifade özel karakteri varsa çalışmaz.
haridsv

3

İçin zshsözdizimi biraz farklı, ama burada en yanıtlardan daha hala kısadır:

> str1='mAtCh'
> str2='MaTcH'
> [[ "$str1:u" = "$str2:u" ]] && echo 'Strings Match!'
Strings Match!
>

Bu, karşılaştırmadan önce her iki dizeyi de büyük harfe dönüştürür.


Başka bir yöntem globbing flags, iglob bayrağını kullanarak büyük / küçük harfe duyarsız eşleşmeyi doğrudan kullanmamızı sağlayan zsh'leri kullanır :

setopt extendedglob
[[ $str1 = (#i)$str2 ]] && echo "Match success"
[[ $str1 = (#i)match ]] && echo "Match success"


1

Bu harika bloga / öğreticiye / büyük / küçük harfe duyarlı kalıpla ilgili her ne olursa olsun karşılaştım . Aşağıdaki üç yöntem, örneklerle ayrıntılı olarak açıklanmıştır:

1. tr komutunu kullanarak deseni küçük harfe dönüştürün

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. Büyük / küçük harf kalıplarında normal ifade kullanın

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. Nocasematch'i açın

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.