단어에 특정 문자가 포함되어 있으면 true를 반환하려면 if 문이 필요합니다. 예를 들어:
var="information"
if [ $var contain "i" ]; then
....
else
...
fi
답변1
switch
또는 case
이와 유사한 것을 사용하는 것은 어떻습니까?
#!/bin/sh
v="information"
case $v in
*f*)
echo "found \"f\" in ${v}";;
*)
echo "no match found in ${v}"
esac
exit
바늘이 변수에 저장되어 있는 경우 패턴으로 간주되지 않도록 인용하는 것이 중요합니다.
case $haystack in
*"$needle"*) echo match
esac
그것이 없으면, 예를 들어 어떤 $needle
경우 *
에도 ?
일치합니다.커다란 건초 더미(각각 비어 있지 않은 건초 더미)
어쨌든 $needle
반드시 단일 문자일 필요는 없습니다 . 어떤 문자열에서도 작동합니다.
많은 쉘에서는 비어 있지 않은 바이트 시퀀스에서도 작동합니다. 유효한 문자를 형성하지 않더라도 모든 바이트가 문자로 분리되는 것은 아닙니다. 예를 들어 é
일부 구현에서는 UTF-8(0xc3 0xa9)로 인코딩된 문자열에서 0xc3 바이트를 찾을 수 없습니다. 반대로, 로케일의 인코딩 i
이 0xa3 0x69(ASCII와 같은 0x69) 인코딩을 갖는 BIG5-HKSCS인 경우 일부 쉘이 내부적으로 발견될 수 있습니다.ξ
ξ
i
답변2
Bash의 [[ ... ]]
테스트는 패턴 일치와 정규식을 이해합니다.
==
and 연산자를 사용하는 경우!=
연산자 오른쪽의 문자열을 패턴으로 사용하여 패턴 매칭을 수행합니다. 연산자를 사용하는 경우=~
연산자 오른쪽의 문자열이 정규식으로 일치됩니다.
그래서:
s=information
if [[ $s = *i* ]] ; then echo has i ; fi
인용된 문자열은 문자 그대로 사용됩니다.
if [[ $s = "*i*" ]] ; then echo is i between two asterisks ; fi
정규식을 알고 있습니다
if [[ $s =~ ^.*i.*$ ]] ; then echo has i ; fi
평소와 같이 전체 문자열을 채우지 않는 일치 항목도 필요합니다.
if [[ $s =~ i ]] ; then echo has i ; fi
답변3
이 [[ ... ]]
경우 비교의 오른쪽이 패턴 역할을 합니다.
if [[ $var == *i* ]] ; then
답변4
오래된 (그리고 꽤 이식성이 뛰어난) 방법은 사례문을 사용하는 것입니다:
var="information"
case $var in
*i*) echo "An 'i' was found in $var";;
* ) echo "There is no 'i' in $var";;
esac
한 줄 기능으로:
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(백만) 자 문자열의 경우 각 함수의 타이밍은 다음과 같습니다.
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
긴 문자열의 경우 (regex)가 가장 좋습니다.
기능 t33 ~ s77은 다음과 같이 실행될 경우 실행 시간을 변경합니다.
$ LANG=C ./script
모든 것이 더 빨라집니다.
흥미롭게도 테스트된 문자열이 유효하지 않은 UTF-8 문자열인 경우 함수는 f44
* s77
output false) 오류를 보고합니다. 예를 들면 다음과 같습니다.
$'\x80abcde'
grep(정규식의 기본 명령)이 수행하는 것처럼(utf-8 로케일에서):
$ echo $'\x80abcde' | grep '^.*$' # no output
$ (LANG=C; echo $'\x80abcde' | grep '^.*$')
�abcde