Bir kabuk betiğinde büyük-küçük harf duyarlı alt dize araması [kapalı]


22

Komut çıkışında büyük küçük harf duyarsız bir alt dizgi eşlemesi yapacak bir kabuk betiğini nasıl yazabilirim?


grep -iolabilir?
Ramesh

Bunu senaryomun içine nasıl koyacağım? Acemi bir soru ise özür dilerim. Linux öğrenmeye başladım çünkü stajım için ona ihtiyacım var. Teşekkürler!
Miguel Roque,

1
İstediğiniz şey kabuk komut dosyasıdır - "linux" bir programlama dili değildir, bir işletim sistemi çekirdeğidir. Linux ile en yaygın kullanılan kabuk bash, unix standardınınsh bir üst kümesidir . Bunlardan birine bakarak başlayabilirsiniz: | 1 | | 2 | - Sadece asıl bağlamın ne olduğunu anlamak için.
goldilocks

1
Bu soru şimdi oldukça açık görünüyor ve yardım merkezindeki yönergelere uyuyor. Lütfen başkalarının yararına açılabilir mi?
BobDoolittle

2
Neden bu sorunun açık olmadığını göremiyorum. Net olması için ne eklemeliyim?
Miguel Roque,

Yanıtlar:


11

İlk önce, büyük / küçük harflere uymayan basit bir örnek komut dosyası:

#!/bin/bash
if [ $(echo hello) == hello ]; then
    echo it works
fi

Sağdaki merhaba dize değiştirmeyi deneyin ve artık yankı olmamalıdır it works. echo helloSeçtiğiniz bir komutla değiştirmeyi deneyin . Büyük / küçük harfleri görmezden gelmek istiyorsanız ve hiçbir dize satır sonu içermiyorsa, grep kullanabilirsiniz:

#!/bin/bash
if echo Hello | grep -iqF hello; then
    echo it works
fi

Buradaki anahtar, bir komut çıktısını boruya bağlamanızdır grep. ifBu durumda grep içinde - İfade bir boru hattı en sağdaki komutun çıkış durumu test eder. Grep, ancak bir eşleşme bulduğunda başarılı bir şekilde çıkar.

-iGrep'in seçenek davasını görmezden söylüyor. Seçenek ilk eşleşmeden sonra değil yayarlar çıktı ve çıkmak için söylüyor. Seçenek bir dize yerine normal ifade olarak argüman tedavi etmek söylüyor.
-q
-F

İlk örneğin doğrudan karşılaştırmalar ve çeşitli yararlı operatörler sağlayan kullandığını unutmayın . İkinci form sadece komutları çalıştırır ve çıkış durumlarını test eder.[ expression ]


Gilles'un neden katkıda bulunduğum kodu değiştirmenin gerekli olduğunu düşündüğünü anlamıyorum. Hiçbir şey kırmadı ama işe yaradı. Bu örnekte çift tırnak kullanmanıza gerek yoktur - çıktıda boşluk varsa, bunlar önemlidir. Ve == de aynı şekilde çalışır çünkü sh aslında Linux'ta bashtır. Orjinal Bourne Shell, uzun zamandır bu noktada gitti. Solaris'in bile daha fazla sevk ettiğini sanmıyorum. Bu örnekte gereksiz olsa da, çift tırnakların muhtemelen en iyi uygulama olduğu konusunda hemfikirim, ancak bence, atama ve karşılaştırmayı açıkça ayrı tutmak için bence '=='.
BobDoolittle

Bekle, böylece bir yayın düzenlenebilir mi? Bunu bilmiyordum.
Miguel Roque,

Yeterli üne sahip, evet. Umarım, itibarı yüksek olan birileri, özellikle bu forumdaki kodları, gereksiz düzenlemeleri yapmadan önce iki kez düşünürler. unix.stackexchange.com/help/privileges
BobDoolittle

@BobDoolittle Bazı durumlarda fark yaratabilir, ancak kurulumunuzla değil - bunu bilmek iyi.

2
Uygulamada bunun sadece Bourne kabuğu ile ilgili olmadığını unutmayın. ==POSIX değil. shdeğil bashtüm Linux tabanlı sistemlerde. ==tarafından desteklenmeyen ash(bunun üzerine shbirçok BSD ve Debian türevlerinin en az dayanır) ya da posh, ve alıntı ihtiyaçları zsh. İki katına çıkarmanın anlamı yok =. [sınamak için bir komuttur. Buradaki ödev ve karşılaştırma arasında kesin bir açıklama yapmanıza gerek yoktur. Bu (( a == b ))vs farklı (( a = b)). İle ==başlayan bir komut dosyasında kullanmak #! /bin/shyanlış. Varsayır kshveya bashsözdizimi varsa , #!buna göre güncelleyin .
Stéphane Chazelas

49

Kabuk seçeneğini ayarladıysanız, bashregex operatörünü kullanarak doğal olarak eşleşen büyük / küçük harf duyarlı alt dizgiyi yapabilirsiniz . Örneğin=~nocasematch

s1="hElLo WoRlD"
s2="LO"

shopt -s nocasematch

[[ $s1 =~ $s2 ]] && echo "match" || echo "no match"
match

s1="gOoDbYe WoRlD"
[[ $s1 =~ $s2 ]] && echo "match" || echo "no match"
no match

6
lol! belirsiz kabuk bilgisi için puan.
BobDoolittle

2
Bu seçenek aynı zamanda basit eşleşme operatörünü de etkiler. [[ XYZ == xyz ]] && echo "match"=>match
itsadok

7

Değişken needledeğerindeki değişken değerinin büyük / küçük harf duyarlı bir dize araması için haystack:

case "$haystack" in
  *"$needle"*) echo "present";
  *) echo "absent";
esac

Büyük / küçük harf duyarlı bir dize araması için her ikisini de aynı duruma dönüştürün.

uc_needle=$(printf %s "$needle" | tr '[:lower:]' '[:upper:]' ; echo .); uc_needle=${uc_needle%.}
uc_haystack=$(printf %s "$haystack" | tr '[:lower:]' '[:upper:]' ; echo .); uc_haystack=${uc_haystack%.}
case "$uc_haystack" in
  *"$uc_needle"*) echo "present";;
  *) echo "absent";;
esac

O Not trGNU coreutils içerisinde baytlı yerel ayarları desteklemeyen (örneğin UTF-8). Çok baytlı yerel ayarlarla çalışma yapmak için bunun yerine awk kullanın. Awk kullanacaksanız, sadece dönüşüm yerine dize karşılaştırmasını yapabilirsiniz.

if awk 'BEGIN {exit !index(toupper(ARGV[2]), toupper(ARGV[1]))}' "$needle" "$haystack"; then
  echo "present"
else
  echo "absent"
fi

trBusyBox dan desteklemediği sözdizimi; bunun yerine kullanabilirsiniz . BusyBox, ASCII dışı yerel ayarları desteklemiyor.[:CLASS:]tr a-z A-Z

Bash (ama sh) sürüm 4.0, sürümünde, büyük / küçük harf dönüşümü için yerleşik bir sözdizimi ve dize eşlemesi için daha basit bir sözdizimi vardır.

if [[ "${haystack^^}" = *"${needle^^}"* ]]; then
  echo "present"
else
  echo "absent"
esac

Bunun birkaç yaşında olduğunun farkındayım, ama tüm bunlar printf | trbaşımı döndürüyor. Mümkünse, komutların çağrılmasını en aza indirgeyin ... v değişkeni verildiğinde, aynı şeyi kullanarak da yapabilirsiniz v=$(tr '[:lower:]' '[:upper:]' <<<$v). Bunu daha önce hiç görmemiş olanlar için <<<, esas olarak bir " <<EOFbelge değişkeni" kullanımı, burada bir belge için olduğu gibidir. Yapma printfya da echokesinlikle yapmanız gerekmedikçe.
Will

@Will Yalnızca <<<operatöre sahip kabukları çalışır : ksh, bash, zsh, ancak düz sh. Ve printfnasıl yürüdüğü konusunda borulara oldukça yakın : Aynı sayıda çağrı var forkve execve( printfyerleşik olarak kabul edilir, ki bu en yaygın mermilerde olduğu gibi); Aradaki fark, <<<boru kullanmak yerine geçici bir dosya oluşturmaktır. <<<yazın iyidir ancak performans iyileştirmesi yapmaz.
Gilles 'SO- kötülük olmayı bırak'
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.