Tengo el codigo
file="JetConst_reco_allconst_4j2t.png"
if [[ $file == *_gen_* ]];
then
echo "True"
else
echo "False"
fi
Pruebo si file
contiene "gen". El resultado es "Falso". ¡Agradable!
El problema es cuando sustituyo "gen" con una variable testseq
:
file="JetConst_reco_allconst_4j2t.png"
testseq="gen"
if [[ $file == *_$testseq_* ]];
then
echo "True"
else
echo "False"
fi
Ahora el resultado es "Verdadero". ¿Como puede ser? ¿Como solucionar el problema?
shell-script
variable
string
control-flow
Viesturs
fuente
fuente
Respuestas:
Debe interpolar la
$testseq
variable con una de las siguientes formas:$file == *_"$testseq"_*
(aquí$testseq
considerado como una cadena fija)$file == *_${testseq}_*
(aquí$testseq
considerado como un patrón).O
_
inmediatamente después del nombre de la variable se tomará como parte del nombre de la variable (es un carácter válido en un nombre de variable).fuente
Use el
=~
operador para hacer comparaciones de expresiones regulares:De esta manera, comparará si
$file
tiene$testseq
en su contenido.Si cambio
testseq="Const"
:Pero tenga cuidado con lo que alimenta
$testseq
. Si la cadena en él de alguna manera representa una expresión regular (como[0-9]
por ejemplo), hay más posibilidades de desencadenar una "coincidencia".Referencia :
fuente
Usar
case ... esac
es una de las formas más sencillas de realizar una coincidencia de patrones de forma portátil. Funciona como una declaración "switch" en otros idiomas (bash
,zsh
yksh93
también le permite hacer caer a través de varias formas incompatibles). Los patrones utilizados son los patrones estándar de nombres de archivo.El problema que tiene se debe al hecho de que
_
es un carácter válido en un nombre de variable. El shell se verá así*_$testseq_*
como "*_
seguido por el valor de la variable$testseq_
y un*
". La variable$testseq_
no está definida, por lo que se expandirá a una cadena vacía y terminará con*_*
, que obviamente coincide con el$file
valor que tiene. Puede esperar obtenerTrue
siempre que el nombre de archivo$file
contenga al menos un guión bajo.Para delimitar correctamente el nombre de la variable, el uso
"..."
alrededor de la expansión:*_"$testseq"_*
. Esto usaría el valor de la variable como una cadena. Si desea utilizar el valor de la variable como patrón , utilice*_${testseq}_*
en su lugar.Otra solución rápida es incluir los guiones bajos en el valor de
$testseq
:y luego simplemente usar
*"$testseq"*
como patrón (para una comparación de cadenas).fuente
*"$testseq"*
decase
igual a[[...]]
(a excepción de zsh a menos que habilite globsubst)