Bir dize alt dize içeriyorsa test edin


40

Kod bende

file="JetConst_reco_allconst_4j2t.png"
if [[ $file == *_gen_* ]];
then
    echo "True"
else
    echo "False"
fi

file"Gen" içeriyorsa test ederim . Çıktı "Yanlış" dır. Güzel!

Sorun, "gen" i bir değişkenle değiştirdiğimde testseq:

file="JetConst_reco_allconst_4j2t.png"
testseq="gen"
if [[ $file == *_$testseq_* ]];
then
    echo "True"
else
    echo "False"
fi

Şimdi çıktı "Doğru". Nasıl olabilir? Sorunu nasıl çözebilirim?


Yanıtlar:


25

$testseqDeğişkeni aşağıdaki yollardan biriyle enterpolasyon etmeniz gerekir :

  • $file == *_"$testseq"_*(burada $testseqsabit bir dize olarak kabul edilir)

  • $file == *_${testseq}_*(burada $testseqbir model olarak kabul edilir).

Veya _değişkenin isminden hemen sonra değişkenin isminin bir parçası olarak alınacaktır (değişken ismindeki geçerli bir karakter).


OP için geçerli olan doğru cevap, ancak taşınabilir olması. (Bu verilen cevapların eleştirisi değildir, sadece okuyuculara bir uyarıdır). ;-)
Cbhihe 7:18

28

=~Düzenli ifade karşılaştırmaları yapmak için operatörü kullanın :

#!/bin/bash
file="JetConst_reco_allconst_4j2t.png"
testseq="gen"
if [[ $file =~ $testseq ]];
then
    echo "True"
else
    echo "False"
fi

Bu yolla, bu karşılaştıracaktır $filevardır $testseqiçeriğini üzerinde.

user@host:~$ ./string.sh
False

Eğer değiştirirsem testseq="Const":

user@host:~$ ./string.sh
True

Ancak, neyle beslendiğinize dikkat edin $testseq. Eğer dizginin bir kısmı regex'i temsil ediyorsa (örneğin [0-9], gibi) bir "eşleşmeyi" tetikleme şansı daha yüksektir.

Referans :


20
file="JetConst_reco_allconst_4j2t.png"
testseq="gen"

case "$file" in
    *_"$testseq"_*) echo 'True'  ;;
    *)              echo 'False'
esac

Kullanımı case ... esac, desen eşleştirmesini taşınabilir bir şekilde gerçekleştirmenin en basit yollarından biridir. Farklı dillerde bir "switch" ifadesi olarak çalışıyor ( bash, zshve ksh93ayrıca yapmanızı sağlar sonbahar-yoluyla çeşitli uyumsuz yollarla). Kullanılan desenler, standart dosya adı globbing desenleridir.

Sahip olduğunuz sorun, _değişken isminde geçerli bir karakter olması gerçeğinden kaynaklanıyor . Böylece kabuk, *_$testseq_*" *_değişken $testseq_ve ardından " değerini izleyecektir *. Değişken $testseq_tanımsız, bu nedenle boş bir dizgeye genişletilecek ve sonunda sahip olduğunuz değerle *_*eşleşen açık bir şekilde bulunacaktır $file. TrueDosya adı $fileen az bir alt çizgi içerdiği sürece elde edersiniz .

Düzgün değişkenin, kullanım adını sınırlandırmak için "..."genişleme etrafında: *_"$testseq"_*. Bu, değişkenin değerini bir dizge olarak kullanır. Değişkenin değerini desen olarak kullanmak ister misiniz , *_${testseq}_*yerine kullanın.

Diğer bir hızlı düzeltme, alt çizgi değerine aşağıdakileri eklemektir $testseq:

testseq="_gen_"

ve sonra sadece *"$testseq"*desen olarak kullanın (string karşılaştırması için).


Bu nedenle kabuk $ testseq_ değişkenini arayacak ve bulmayacak ve boş bir dizeyle değiştirilecektir.
Viesturs

@Viesturs Bu konunun kalbi, evet.
Kusalananda

1
Bir alt dize için olması gerektiği arama *"$testseq"*için casebenzerleri için [[...]](zsh için etkinleştirmek sürece hariç globsubst)
Stéphane Chazelas
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.