Testaa, sisältääkö merkkijono alamerkkijonon

Minulla on koodi

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

Testaan jos file sisältää ”gen”. Tulos on ”False”. Hienoa!

Ongelma on, kun korvataan ”gen” muuttujalla testseq:

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

Nyt tulos on ”True”. Kuinka se voisi olla? Kuinka korjata ongelma?

Kommentit

Vastaa

Sinun on interpoloitava $testseq muuttuja jollakin seuraavista tavoista:

  • $file == *_"$testseq"_* (tässä $testseq pidetään kiinteänä merkkijonona)

  • $file == *_${testseq}_* (tässä $testseq pidetään malli).

Tai _ heti muuttujan nimen jälkeen otetaan osaksi muuttujaa nimi (se on kelvollinen merkki muuttujan nimessä).

Kommentit

  • Oikea vastaus, koska se koskee OP: ta, mutta ei ole kannettava . (Tämä ei ole kritiikkiä annetusta vastauksesta, vain varoitus lukijoille). 😉

Vastaa

Käytä operaattoria =~ tai tehdä säännöllisen lausekkeen vertailuja:

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

Tällä tavoin se vertaa, onko $file -kohdassa $testseq sen sisällöstä.

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

Jos muutan testseq="Const":

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

Mutta ole varovainen syötteesi kanssa $testseq. Jos siinä oleva merkkijono edustaa jotenkin regexiä (kuten esimerkiksi [0-9]), on suurempi mahdollisuus käynnistää ”ottelu”.

Viite :

kommentit

  • Näyttää siltä, että tämä vastaus on " bash "

vastaus

file="JetConst_reco_allconst_4j2t.png" testseq="gen" case "$file" in *_"$testseq"_*) echo "True" ;; *) echo "False" esac 

case ... esac -toiminnon käyttäminen on yksi yksinkertaisimmista tavoista suorittaa kuvion haku kannettavalla tavalla. Se toimii ”switch” -käskynä muilla kielillä (bash, zsh ja ksh93 mahdollistaa myös pudotuksen tekemisen useilla yhteensopimattomilla tavoilla). Käytetyt mallit ovat tavallisia tiedostonimiä, jotka ovat hölynpölyä.

Kohtaamasi ongelma johtuu siitä, että _ on kelvollinen merkki muuttujan nimessä. Kuori näyttää siten *_$testseq_* nimellä ”*_, jota seuraa muuttujan $testseq_ arvo ja * ”. Muuttuja $testseq_ on määrittelemätön, joten se laajennetaan tyhjäksi merkkijonoksi, ja päädyt kohtaan *_*, joka selvästi vastaa div id = ”db3c2b02d3″>

arvo, joka sinulla on. Saatat odottaa saavan True, kunhan tiedostonimi $file sisältää vähintään yhden alaviivan.

Oikein rajaa muuttujan nimi, käytä "..." laajennuksen ympärillä: *_"$testseq"_*. Tämä käyttäisi muuttujan arvoa merkkijonona. Haluatko käyttää muuttujan arvoa mallina , käytä sen sijaan *_${testseq}_*.

Toinen pikakorjaus on sisällyttää alleviivaa arvon $testseq arvossa:

testseq="_gen_" 

ja käytä sitten vain *"$testseq"* kuviona (merkkijonojen vertailua varten).

Kommentit

  • Joten kuori etsii muuttujaa $ testseq_ eikä löydä se ja korvaa se tyhjällä merkkijonolla.
  • @Viesturs Tämä ' s on ongelman ydin, kyllä.
  • alahakuhakun pitäisi olla *"$testseq"* case, kuten [[...]] (paitsi zsh, ellet ota globsubst käyttöön)
  • Yksinkertaisempi kuin [ "${str##*substr*}" ] || echo True?
  • @Isaac Mitä lukea ja ymmärtää mitä ' s tapahtuu, kyllä. ' on myös helppo pidentää yhtä testiä useammalla testitapauksella saamatta " if-then-elif-then-elif " spagetti. Vaikka yhden merkkijonon testaaminen näytetyllä tavalla (katoako merkkijono korvikkeessa) on lyhyempi.

vastaus

Jos haluat testata, sisältääkö merkkijono alamerkkijonoa, kannettava tapa käyttää:

file="JetConst_reco_allconst_4j2t.png"; testseq="gen" [ "${file##*$testseq*}" ] || echo True Substring is present 

Tai "${file##*"$testseq"*}", jotta vältetään globaalien merkkien tulkinta testseq.

Kommentit

  • Tarvitset ' tarvitset jotain [" $ {file ## * $ testseq *} "! = " $ tiedosto " ], koska viiva, joka on Poista suurin etuliite -malli.
  • Ei, @NoelGrandin ei muutu useimmissa kuoreissa (mukaan lukien viiva), Suurin etuliitteen malli on koko merkkijono jos muuttujan alamallin ($testseq) arvo sisältyy $file -arvoon. Yritä: dash -c 'file="JetConst_reco_allconst_4j2t.png"; testseq="reco"; echo "=${file##*"$testseq"*}="' vahvistaa, että viiva poistaa koko merkkijonon.

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *