J'ai le code
file="JetConst_reco_allconst_4j2t.png"
if [[ $file == *_gen_* ]];
then
echo "True"
else
echo "False"
fi
Je teste si file
contient "gen". La sortie est "False". Agréable!
Le problème est quand je substitue "gen" avec une variable testseq
:
file="JetConst_reco_allconst_4j2t.png"
testseq="gen"
if [[ $file == *_$testseq_* ]];
then
echo "True"
else
echo "False"
fi
Maintenant, le résultat est "True". Comment est-ce possible? Comment resoudre le probleme?
shell-script
variable
string
control-flow
Viesturs
la source
la source
Réponses:
Vous devez interpoler la
$testseq
variable de l’une des manières suivantes:$file == *_"$testseq"_*
(ici$testseq
considéré comme une chaîne fixe)$file == *_${testseq}_*
(ici$testseq
considéré comme un motif).Ou
_
tout de suite après le nom de la variable sera considéré comme faisant partie du nom de la variable (c'est un caractère valide dans un nom de variable).la source
Utilisez l'
=~
opérateur pour créer des combinaisons d'expressions régulières:De cette façon, il va comparer si
$file
a$testseq
sur son contenu.Si je change
testseq="Const"
:Mais soyez prudent avec ce que vous nourrissez
$testseq
. Si la chaîne qui y figure représente une expression rationnelle (comme[0-9]
par exemple), il y a plus de chance de déclencher une "correspondance".Référence :
la source
L’utilisation
case ... esac
est l’un des moyens les plus simples d’effectuer une correspondance de motif de manière portable. Il fonctionne comme un « switch » dans d' autres langues (bash
,zsh
etksh93
vous permet également de faire fall-through de diverses manières incompatibles). Les modèles utilisés sont les modèles globing de nom de fichier standard.Le problème que vous rencontrez est dû au fait qu'il
_
s'agit d'un caractère valide dans un nom de variable. Le shell va donc voir*_$testseq_*
"*_
suivi de la valeur de la variable$testseq_
et d'un*
". La variable$testseq_
est indéfinie, elle sera donc étendue à une chaîne vide et vous obtiendrez avec*_*
, ce qui correspond évidemment à la$file
valeur que vous avez. Vous pouvez vous attendre à obtenirTrue
aussi longtemps que le nom du fichier$file
contient au moins un trait de soulignement.Pour délimiter correctement le nom de la variable, l' utilisation
"..."
autour de l'extension:*_"$testseq"_*
. Cela utiliserait la valeur de la variable en tant que chaîne. Souhaitez-vous utiliser la valeur de la variable en tant que modèle , utilisez*_${testseq}_*
plutôt.Une autre solution consiste à inclure les traits de soulignement dans la valeur de
$testseq
:et ensuite juste utiliser
*"$testseq"*
comme motif (pour une comparaison de chaîne).la source
*"$testseq"*
pourcase
comme pour[[...]]
(sauf pour zsh moins que vous ne globsubst)[ "${str##*substr*}" ] || echo True
?Pour le moyen portable de tester si une chaîne contient une sous-chaîne, utilisez:
Ou
"${file##*"$testseq"*}"
pour éviter d'interpréter les caractères globaux danstestseq
.la source