我有代码
file="JetConst_reco_allconst_4j2t.png"
if [[ $file == *_gen_* ]];
then
echo "True"
else
echo "False"
fi
我测试是否file
包含“gen”。输出为“假”。好的!
问题是当我用变量替换“gen”时testseq
:
file="JetConst_reco_allconst_4j2t.png"
testseq="gen"
if [[ $file == *_$testseq_* ]];
then
echo "True"
else
echo "False"
fi
现在输出是“True”。怎么会这样?如何解决这个问题?
答案1
使用=~
运算符进行正则表达式比较:
#!/bin/bash
file="JetConst_reco_allconst_4j2t.png"
testseq="gen"
if [[ $file =~ $testseq ]];
then
echo "True"
else
echo "False"
fi
这样,它将比较其内容是否$file
有。$testseq
user@host:~$ ./string.sh
False
如果我改变testseq="Const"
:
user@host:~$ ./string.sh
True
但是,要小心你吃的东西$testseq
。如果其上的字符串以某种方式表示正则表达式(例如[0-9]
),则触发“匹配”的机会更高。
参考:
答案2
您需要使用$testseq
以下方式之一来插入变量:
$file == *_"$testseq"_*
(这里$testseq
视为固定字符串)$file == *_${testseq}_*
(这里$testseq
被视为一种模式)。
或者_
紧随变量名称之后的字符将被视为变量名称的一部分(它是变量名称中的有效字符)。
答案3
file="JetConst_reco_allconst_4j2t.png"
testseq="gen"
case "$file" in
*_"$testseq"_*) echo 'True' ;;
*) echo 'False'
esac
使用case ... esac
是以可移植的方式执行模式匹配的最简单方法之一。它在其他语言中用作“switch”语句(bash
、zsh
、 ,并且ksh93
还允许您执行跌倒以各种不兼容的方式)。使用的模式是标准文件名通配模式。
您遇到的问题是由于_
变量名称中的字符是有效的。因此,shell 将看到*_$testseq_*
“*_
后跟变量值$testseq_
和*
”。该变量$testseq_
未定义,因此它将扩展为空字符串,最终得到*_*
,它显然与$file
您拥有的值匹配。您可能期望得到的True
文件名至少$file
包含一个下划线。
要正确分隔变量名称,请使用"..."
扩展名:*_"$testseq"_*
。这会将变量的值用作字符串。您想使用变量的值作为图案,*_${testseq}_*
改为使用。
另一个快速修复方法是在 的值中包含下划线$testseq
:
testseq="_gen_"
然后用作*"$testseq"*
模式(用于字符串比较)。
答案4
对于测试字符串是否包含子字符串的可移植方法,请使用:
file="JetConst_reco_allconst_4j2t.png"; testseq="gen"
[ "${file##*$testseq*}" ] || echo True Substring is present
或者"${file##*"$testseq"*}"
避免解释testseq
.