ZaLinux.ru

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

Есть строка Bash:

string="My string"

Как в Bash можно протестировать, содержит ли она другую строку?

Рассмотрим сразу несколько вариантов, с использованием различных программ: какие-то будут быстрее или медленнее, какие-то решения будут работать только в Bash, а некоторые в любой оболочке Linux.

1.

Вариант с обрамлением строки подстановочными символами:

string='Моя длинная строка'
if [[ $string == *"Моя длинная"* ]]; then
  echo "Подстрока найдена!"
fi

Обратите внимание, что пробелы в искомой подстроке должны быть заключены в двойные кавычки, а звёздочки должны быть снаружи — в точности как на примере. Также обратите внимание, что используется простое сравнение (то есть ==), а не оператор регулярных выражений (то есть не =~).

Также не забывайте делать пробелы до и после квадратных скобок.

Если поменять строки местами, то для проверки поменяйте == на != и результат будет точно таким же.

2.

Вариант с регулярными выражениями

string=Моя строка';

if [[ $string =~ "Моя" ]]
then
   echo "Подстрока найдена!"
fi

Чтобы проверить, что строка НЕ содержит подстроку:

[[ ! "abc" =~ "d" ]]

Пример выше вернёт true.

3.

Похожего эффекта можно добиться и с выражением case:

case "$string" in 
  *foo*)
    # Do stuff
    ;;
esac

Это решение является портативным на оболочки posix (то есть это не башизм).

4.

Следующая функция возвращает True или False в зависимости от того, содержит ли одна строка другую или нет. То есть эту

stringContain() { [ -z "$1" ] || { [ -z "${2##*$1*}" ] && [ -n "$2" ];};}

Вызов функции использовать так:

stringContain 'ИСКОМАЯ ПОДСТРОКА' 'БОЛЬШАЯ СТРОКА'

Например:

stringContain() { [ -z "$1" ] || { [ -z "${2##*$1*}" ] && [ -n "$2" ];};};
if stringContain 'bcd' 'abcdef'; then echo yes; else echo no; fi
yes

Пример, когда подстрока не найдена:

stringContain() { [ -z "$1" ] || { [ -z "${2##*$1*}" ] && [ -n "$2" ];};};
if stringContain 'ddd' 'abcdef'; then echo yes; else echo no; fi
yes

5.

Вы должны помнить, что сценарии оболочки — это не столько язык, сколько набор команд. Инстинктивно вы думаете, что этот «язык» требует, чтобы за if следовало [ или [[ с помощью которых выполняется тестирование. Обе они являются просто командами, которые возвращают состояние выхода, указывающее на успех или неудачу (как и любая другая команда). По этой причине я бы использовал grep, а не команду [.

Просто сделайте:

if grep -q foo <<<"$string"; then
    echo "It's there"
fi

Теперь, когда вы воспринимаете if как тестирование статуса выхода команды, которая следует за ним (завершена точкой с запятой), почему бы не пересмотреть источник строки, которую вы тестируете?

## вместо этого
filetype="$(file -b "$1")"
if grep -q "tar archive" <<<"$filetype"; then
#...

## просто сделайте это
if file -b "$1" | grep -q "tar archive"; then
#...

Опция -q делает так, что grep ничего не выводит поскольку мы только хотим только код возврата

Можно использовать подстановку процесса:

if grep -q foo <(echo somefoothing); then

Смотрите также:

Рекомендуемые статьи:

Оставить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *