2013-05-17 4 views
0

У меня есть следующие строки в БашКак проверить, является ли строка подстрокой другого?

str1="any string" 
str2="any" 

Я хочу, чтобы проверить, если str2 подстрока str1

я могу это сделать таким образом:

c=`echo $str1 | grep $str2` 
if [ $c != "" ]; then 
    ... 
fi 

Есть ли еще эффективный способ сделать это?

+0

'if [-n $ c]' ... – DevSolar

ответ

4

Вы можете использовать расширение wild-card *.

str1="any string" 
str2="any" 

if [[ "$str1" == *"$str2"* ]] 
then 
    echo "str2 found in str1" 
fi 

Обратите внимание, что * расширение не будет работать с одним [ ].

+0

Необходимы ли в этом случае кавычки? Я думал, что одно из основных преимуществ '[[]]' over '[]' делало цитаты ненужными ... – DevSolar

+1

Правда. Он кусает, если я скучаю по нему, когда это необходимо, но дополнительный не повредит. Это одна из тех вещей, за которые я заставляю себя делать это всегда ;-) –

+1

@downvoter любая действительная причина? –

1

Вы можете использовать Баш сопоставления регулярных выражений без использования grep:

if [[ $str1 =~ $str2 ]]; then 
    ... 
fi 

Обратите внимание, что вам не нужны какие-либо окружающие слэш или кавычки для шаблона регулярного выражения. Если вы хотите использовать сопоставление шаблонов glob, просто используйте == вместо =~ в качестве оператора.

Некоторые примеры могут быть найдены here.

3
str1="any string" 
str2="any" 

Старая школа (Bourne стиль оболочки):

case "$str1" in *$str2*) 
    echo found it 
esac 

Новая школа (как speakr шоу), однако имейте в виду, что строка справа будет рассматриваться как регулярное выражение:

if [[ $str1 =~ $str2 ]] ; then 
    echo found it 
fi 

Но это тоже будет работать, даже если вы точно не ожидали его:

str2='.*[trs].*' 
if [[ $str1 =~ $str2 ]] ; then 
    echo found it 
fi 

Использование grep происходит медленно, так как оно порождает отдельный процесс.

+1

+1 для выражения 'case'. Но это не старая школа, это современное состояние **, потому что это как портативный POSIX-порт. BTW, не нужно указывать $ str1; после «случая» нет разделения слов. – Jens

+0

Я бы не предполагал, что все существующие хосты Unix имеют текущий стандарт POSIX. Выражение этого случая совместимо с гораздо более старыми системами, чем синтаксис [[... = ~ ...]] - десятилетиями старше. Поэтому * много * более портативный. –

+1

Тогда мы находимся в жестоком согласии. 'Case' способ поиска подстрок работает с любой оболочкой Bourne, так что это современное состояние и безусловно безоговорочно. Любой, кто использует bashisms вроде '[[]]', нуждается в уроке переносимости. :-) – Jens

Смежные вопросы