У меня есть код
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». Как это могло произойти? Как решить проблему?
shell-script
variable
string
control-flow
Виестура
источник
источник
Ответы:
Вам необходимо интерполировать
$testseq
переменную одним из следующих способов:$file == *_"$testseq"_*
(Вот$testseq
рассматривается как фиксированная строка)$file == *_${testseq}_*
(здесь$testseq
рассматривается как образец).Или
_
сразу после имени переменной будет взято как часть имени переменной (это допустимый символ в имени переменной).источник
Используйте
=~
оператор для сравнения регулярных выражений:Таким образом, он будет сравнивать, если
$file
имеет$testseq
по своему содержанию.Если я изменюсь
testseq="Const"
:Но будьте осторожны с тем, что вы кормите
$testseq
. Если строка на нем каким-либо образом представляет регулярное выражение (как,[0-9]
например), есть больше шансов вызвать "совпадение".Ссылка :
источник
Использование
case ... esac
- это один из самых простых способов выполнить сопоставление с образцом переносимым способом. Он работает как оператор «switch» на других языках (bash
,zsh
иksh93
также позволяет выполнять сквозные операции различными несовместимыми способами). Используемые шаблоны являются стандартными шаблонами подстановки имен файлов.Проблема, с которой вы столкнулись, связана с тем, что
_
это допустимый символ в имени переменной. Оболочка, таким образом, будет выглядеть*_$testseq_*
как «*_
сопровождаемая значением переменной$testseq_
и an*
». Переменная$testseq_
не определена, поэтому она будет расширена до пустой строки, и вы в итоге получите*_*
, что, очевидно, соответствует$file
значению, которое у вас есть. Вы можете рассчитывать получитьTrue
до тех пор, пока имя файла$file
содержит хотя бы одно подчеркивание.Для того, чтобы правильно разграничить имя переменной, использование
"..."
вокруг расширения:*_"$testseq"_*
. Это будет использовать значение переменной в виде строки. Если вы хотите использовать значение переменной в качестве шаблона , используйте*_${testseq}_*
вместо этого.Еще одно быстрое решение - включить подчеркивание в значение
$testseq
:а затем просто использовать
*"$testseq"*
в качестве шаблона (для сравнения строк).источник
*"$testseq"*
дляcase
как для[[...]]
(за исключением Zsh , если не включить globsubst)[ "${str##*substr*}" ] || echo True
?Для переносимого способа проверить, содержит ли строка подстроку, используйте:
Или
"${file##*"$testseq"*}"
чтобы не интерпретировать символы глобуса вtestseq
.источник