Megvan a kódom
file="JetConst_reco_allconst_4j2t.png" if [[ $file == *_gen_* ]]; then echo "True" else echo "False" fi
Tesztelek ha a file tartalmazza a “gen” szót. A kimenet “hamis”. Szép!
A probléma az, amikor a “gen” szót egy testseq változóval helyettesítem:
file="JetConst_reco_allconst_4j2t.png" testseq="gen" if [[ $file == *_$testseq_* ]]; then echo "True" else echo "False" fi
Most a kimenet “True”. Hogy lehetséges ez? Hogyan lehet kijavítani a problémát?
Megjegyzések
- A Shell teszt lehetséges másolata a minta megtalálásához karakterláncban
Válasz
Interpolálni kell a $testseq változó a következő módok egyikével:
-
$file == *_"$testseq"_*(itt$testseqrögzített karakterláncnak tekinthető) -
$file == *_${testseq}_*(itt$testseqegy minta).
Vagy a _ közvetlenül a változó neve után bekerül a változó s részébe név (ez egy érvényes karakter egy változó nevében).
Megjegyzések
- Helyes válasz, mivel az OP-ra vonatkozik, de nem hordozható . (Ez nem a megadott válasz kritikája, csupán figyelmeztetés az olvasókra). 😉
Válasz
Használja a =~ operát vagy rendszeres kifejezés-összehasonlítások:
#!/bin/bash file="JetConst_reco_allconst_4j2t.png" testseq="gen" if [[ $file =~ $testseq ]]; then echo "True" else echo "False" fi
Így összehasonlítja, ha a $file $testseq tartalmát.
user@host:~$ ./string.sh False
Ha megváltoztatom a következőt: testseq="Const":
user@host:~$ ./string.sh True
De vigyázzon azzal, amit $testseq táplál. Ha a rajta lévő karakterlánc valamilyen módon egy regexet képvisel (például [0-9]), akkor nagyobb az esély a “mérkőzés” kiváltására.
Hivatkozás :
megjegyzések
- Úgy tűnik, hogy ez a válasz a " bash "
válasz
file="JetConst_reco_allconst_4j2t.png" testseq="gen" case "$file" in *_"$testseq"_*) echo "True" ;; *) echo "False" esac
A case ... esac használata az egyik legegyszerűbb módszer a mintaillesztés hordozható módon történő végrehajtására. “Switch” utasításként működik más nyelveken (bash, zsh és ksh93 azt is lehetővé teszi, hogy átesést végezzenek, különböző kompatibilis módon). A felhasznált minták a szokásos fájlnévi hullámzó minták.
A probléma annak a ténynek tudható be, hogy a _ egy érvényes karakter egy változónévben. A héj tehát *_$testseq_* -et “*_ néven fogja látni, amelyet a $testseq_ változó értéke követ. és egy * “. A $testseq_ változó nincs meghatározva, ezért kibővül egy üres karakterláncra, és végül a *_* változóra kerül, ami nyilvánvalóan megegyezik a $file értéke. Arra számíthat, hogy True megkapja, amennyiben a $file fájlnév legalább egy aláhúzást tartalmaz.
A megfelelő működéshez határozza meg a változó nevét, használja a "..." elemet a kibővítés körül: *_"$testseq"_*. Ez a változó értékét karakterláncként használná. Szeretné a változó értékét mintaként használni, használja helyette az *_${testseq}_* szót.
Egy másik gyors javítás a aláhúzza az $testseq értékét:
testseq="_gen_"
, majd csak használja a *"$testseq"* mint a minta (a karakterláncok összehasonlításához).
Megjegyzések
- Tehát a shell a $ testseq_ változót keresi, és nem fogja megtalálni és helyettesítsen egy üres karakterlánccal.
- @Viesturs Ez a ' s a kérdés középpontjában, igen.
- Egy alkönyvtár keresésnek
*"$testseq"*kell lenniecaseszámára, mint például a[[...]](kivéve a engedélyezze a globsubst engedélyezését) - Egyszerűbb, mint a
[ "${str##*substr*}" ] || echo True? - @Isaac Mit olvasni és megérteni szempontjából ' s történik, igen. ' is könnyű egy tesztet meghosszabbítani több tesztesettel anélkül, hogy " if-then-elif-then-elif " spagetti. Bár egyetlen karakterláncot úgy tesztelhet, ahogyan megmutatja (eltűnik-e egy karakterlánc egy helyettesítésben), az rövidebb.
Válasz
A hordozható mód teszteléséhez, hogy egy karakterlánc tartalmaz-e alszöveget, használja:
file="JetConst_reco_allconst_4j2t.png"; testseq="gen" [ "${file##*$testseq*}" ] || echo True Substring is present
Vagy "${file##*"$testseq"*}", hogy elkerülje a globális karakterek értelmezését a testseq.
Megjegyzések
- Szüksége van ' olyasmire, mint [" $ {file ## * $ testseq *} "! = " $ file " ], mert a kötőjelben, amely a Legnagyobb előtag minta eltávolítása.
- Nem, @NoelGrandin a legtöbb kagylóban (beleértve a kötőjelet) nincs változás, a Legnagyobb előtag minta lesz az egész karakterlánc ha a változó alminta (
$testseq) értéke a$fileértéken belül található. Próbálja meg:dash -c 'file="JetConst_reco_allconst_4j2t.png"; testseq="reco"; echo "=${file##*"$testseq"*}="'megerősíteni, hogy a kötőjel eltávolítja az egész karakterláncot.