Eu tenho o código
file="JetConst_reco_allconst_4j2t.png"
if [[ $file == *_gen_* ]];
then
echo "True"
else
echo "False"
fi
Eu testei se file
contém "gen". A saída é "False". Agradável!
O problema é quando substituo "gen" por uma variável testseq
:
file="JetConst_reco_allconst_4j2t.png"
testseq="gen"
if [[ $file == *_$testseq_* ]];
then
echo "True"
else
echo "False"
fi
Agora a saída é "True". Como isso poderia ser? Como resolver o problema?
shell-script
variable
string
control-flow
Viesturs
fonte
fonte
Respostas:
Você precisa interpolar a
$testseq
variável de uma das seguintes maneiras:$file == *_"$testseq"_*
(Aqui$testseq
considerado como uma sequência fixa)$file == *_${testseq}_*
(aqui$testseq
considerado como um padrão).Ou o
_
imediatamente após o nome da variável será considerado como parte do nome da variável (é um caractere válido em um nome de variável).fonte
Use o
=~
operador para fazer comparações de expressões regulares:Dessa forma, ele irá comparar se
$file
tiver$testseq
em seu conteúdo.Se eu mudar
testseq="Const"
:Mas tenha cuidado com o que você alimenta
$testseq
. Se a string nela mostrar um regex (como[0-9]
por exemplo), há mais chances de acionar uma "correspondência".Referência :
fonte
Usar
case ... esac
é uma das maneiras mais simples de executar uma correspondência de padrões de maneira portátil. Ele funciona como uma declaração de "switch" em outros idiomas (bash
,zsh
eksh93
também permite que você faça queda-through de várias maneiras incompatíveis). Os padrões usados são os padrões de globbing do nome do arquivo padrão.O problema que você está enfrentando se deve ao fato de
_
ser um caractere válido em um nome de variável. O shell será visto*_$testseq_*
como "*_
seguido pelo valor da variável$testseq_
e um*
". A variável$testseq_
é indefinida, portanto ela será expandida para uma sequência vazia e você terminará com*_*
, o que obviamente corresponde ao$file
valor que você possui. Você pode esperar obterTrue
o nome do nome do arquivo$file
contido em pelo menos um sublinhado.Para delimitar corretamente o nome da variável, o uso
"..."
em torno da expansão:*_"$testseq"_*
. Isso usaria o valor da variável como uma sequência. Deseja usar o valor da variável como um padrão , use em*_${testseq}_*
vez disso.Outra solução rápida é incluir os sublinhados no valor de
$testseq
:e use apenas
*"$testseq"*
como padrão (para uma comparação de cadeias).fonte
*"$testseq"*
paracase
like[[...]]
(exceto zsh, a menos que você ative o globsubst)