Старый (и вполне переносимый) способ сделать это — использовать оператор case:
var="information"
case $var in
*i*) echo "An 'i' was found in $var";;
* ) echo "There is no 'i' in $var";;
esac
Как одну строку function:
a="information" b="i"
one(){ case $a in (*${b}*) true;; (*) false;; esac; }
И используется с:
if one; then
echo "Found %b in $a";
else
echo "The character '$b' was not found in the string '$a'"
fi
Другими допустимыми способами выполнения той же проверки являются:
two(){ [[ $a == *"$b"* ]] ; } # Using a pattern match.
t33(){ [[ $a =~ "$b" ]] ; } # Extended Regex (ERE) match.
f44(){ [[ $a =~ ^.*"$b".*$ ]] ; } # Using a ERE with limits.
f55(){ [[ ${a//[!"${b}"]} ]] ; } # Removing all non-matching chars.
six(){ [ ! "$a" = "${a%"$b"*}" ] ; } # Using char removal.
s77(){ [[ $a =~ ^.*$ ]] ; } # Testing if string is valid.
Все функции работают с допустимыми строками.
Временные параметры каждой функции для строк из 10, 100, 1000, …, 1000000 (1 миллион) символов приведены ниже:
Number of characters in the string.
10 100 1000 10000 100000 1000000
one 0.024m 0.036m 0.047m 0.207m 2.117m 25.363m
two 0.028m 0.030m 0.043m 0.179m 2.081m 25.337m
t33 0.044m 0.041m 0.053m 0.151m 1.757m 22.695m
f44 0.064m 0.075m 0.241m 1.864m 19.489m 198.488m
f55 0.055m 0.182m 5.275m 421.886m
six 0.043m 0.057m 0.297m 13.987m
s77 0.056m 0.061m 0.154m 1.201m 12.749m 134.774m
Количество символов создается путем повторения символа.
Тестируемая строка строится примерно так:
a="$1$(repeat "$2" 10**$k)$3"
Скрипт вызывается так:
$ ./script start a ending
Функция f55
становится очень медленной, если размер обрабатываемой строки превышает (около) 1000 символы. То же самое происходит с функцией six
для строк длиннее (около) 10000 (10k) символов.
Функция two
работает быстрее для коротких строк, а t33
(регулярное выражение) лучше всего подходит для длинных строк.
Функции с t33 по s77 изменяют время выполнения, если выполняются как:
$ LANG=C ./script
Все становятся быстрее.
Интересно отметить, что функции f44
и s77
сообщат об ошибке *output false), если проверяемая строка является недопустимой строкой utf-8, например:
$'\x80abcde'
Точно так же, как это делает grep (базовая команда для регулярных выражений) (в локали utf-8):
$ echo $'\x80abcde' | grep '^.*$' # no output
$ (LANG=C; echo $'\x80abcde' | grep '^.*$')
�abcde