Проверьте, содержит ли строка строку подстроки

У меня есть код

file="JetConst_reco_allconst_4j2t.png" if [[ $file == *_gen_* ]]; then echo "True" else echo "False" fi 

Я проверяю, содержит ли file «gen». Выход «False». Ницца!

Проблема заключается в том, что я testseq «gen» переменной testseq :

 file="JetConst_reco_allconst_4j2t.png" testseq="gen" if [[ $file == *_$testseq_* ]]; then echo "True" else echo "False" fi 

Теперь выход «True». Как это могло произойти? Как решить проблему?

3 Solutions collect form web for “Проверьте, содержит ли строка строку подстроки”

Вам нужно интерполировать переменную $testseq одним из следующих способов:

  • $file == *_"$testseq"_* (здесь $testseq рассматривается как фиксированная строка)

  • $file == *_${testseq}_* (здесь $testseq рассматривается как шаблон).

 file="JetConst_reco_allconst_4j2t.png" testseq="gen" case "$file" in *_${testseq}_*) echo 'True' ;; *) echo 'False' ;; esac 

Использование case ... esac – один из самых простых способов выполнить сопоставление шаблонов переносимым способом. Он работает как оператор «switch» на других языках ( bash и ksh93 также позволяют вам делать ksh93 различными способами). Используемые шаблоны – это шаблоны шаблонов стандартных имен файлов.

Проблема, с которой вы сталкиваетесь, связана с тем, что _ является допустимым символом в имени переменной. Таким образом, оболочка увидит *_$testseq_* как « *_ за которым следует значение переменной $testseq_ и a * . Переменная $testseq_ не определена, поэтому она будет расширена до пустой строки, и вы получите *_* , что, очевидно, соответствует. Поэтому вы можете ожидать True если имя файла в $file содержит хотя бы одно подчеркивание.

Чтобы правильно разграничить имя переменной, используйте {...} вокруг своего имени: *_${testseq}_* .

Еще одно быстрое решение – включить $testseq подчеркивания в значение $testseq :

 testseq="_gen_" 

а затем просто используйте *$testseq* в качестве шаблона.

Для выполнения регулярных выражений используйте оператор =~ :

 #!/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 . Если строка на нем somehows представляет собой регулярное выражение (например, [0-9] ), появляется больше шансов вызвать «совпадение».

Ссылка :

  • Расширенное руководство по скрипту Bash
  • Назначить имя хоста переменной в ksh
  • Как использовать глобальные переменные массивы в псевдонимах или функциях
  • Поведение задания массива
  • Невозможно назначить вывод вложенных команд переменной в bash
  • Использование sed в сценарии оболочки с многострочными переменными
  • Как использовать расширенное значение переменной оболочки в имени другой переменной?
  • Область переменных в while-read-loop на Solaris
  • Как сохранить статус последнего выхода после теста
  • Что означает «$ {x %% *}» в sh?
  • Shell: как использовать 2 переменные с условием
  • Вставка переменных в команду в сценарии оболочки
  • Linux и Unix - лучшая ОС в мире.