Bash에 문자열이 있습니다.
string="My string"
다른 문자열이 포함되어 있는지 어떻게 테스트 할 수 있습니까?
if [ $string ?? 'foo' ]; then
echo "It's there!"
fi
??
알 수없는 운영자는 어디에 있습니까 ? 에코와를 사용 grep
합니까?
if echo "$string" | grep 'foo'; then
echo "It's there!"
fi
약간 서투른 것 같습니다.
답변
당신은 사용할 수 있습니다 마커스의 대답 (* 와일드 카드)를 사용하면 이중 괄호를 사용하는 경우도 case 문 밖에서 :
string='My long string'
if [[ $string == *"My long"* ]]; then
echo "It's there!"
fi
needle string의 공백은 큰 따옴표로 묶어야하며 *
와일드 카드는 외부에 있어야합니다. 또한 ==
정규 비교 연산자가 아닌 간단한 비교 연산자가 사용됩니다 =~
.
답변
정규식 접근 방식을 선호하는 경우 :
string='My string';
if [[ $string =~ "My" ]]
then
echo "It's there!"
fi
답변
if 문을 사용할지는 확실하지 않지만 case 문을 사용하면 비슷한 효과를 얻을 수 있습니다.
case "$string" in
*foo*)
# Do stuff
;;
esac
답변
stringContain
변형 (호환 또는 대소 문자 구분)
이 스택 오버플로 답변이 대부분 Bash 에 대해 알려주 듯이이 게시물 맨 아래에 사례 독립적 Bash 함수를 게시했습니다 …
어쨌든 내
호환되는 답변
Bash 전용 기능을 사용하는 답변이 이미 많으 므로 BusyBox 와 같이 기능이 불량한 쉘에서 작동하는 방법이 있습니다 .
[ -z "${string##*$reqsubstr*}" ]
실제로 이것은 다음을 제공 할 수 있습니다.
string='echo "My string"'
for reqsubstr in 'o "M' 'alt' 'str';do
if [ -z "${string##*$reqsubstr*}" ] ;then
echo "String '$string' contain substring: '$reqsubstr'."
else
echo "String '$string' don't contain substring: '$reqsubstr'."
fi
done
이것은 Bash, Dash , KornShell ( ksh
) 및 ash (BusyBox)에서 테스트되었으며 결과는 항상 다음과 같습니다.
String 'echo "My string"' contain substring: 'o "M'.
String 'echo "My string"' don't contain substring: 'alt'.
String 'echo "My string"' contain substring: 'str'.
하나의 기능으로
@EeroAaltonen의 요청에 따라 동일한 쉘에서 테스트 한 동일한 데모 버전이 있습니다.
myfunc() {
reqsubstr="$1"
shift
string="$@"
if [ -z "${string##*$reqsubstr*}" ] ;then
echo "String '$string' contain substring: '$reqsubstr'.";
else
echo "String '$string' don't contain substring: '$reqsubstr'."
fi
}
그때:
$ myfunc 'o "M' 'echo "My String"'
String 'echo "My String"' contain substring 'o "M'.
$ myfunc 'alt' 'echo "My String"'
String 'echo "My String"' don't contain substring 'alt'.
참고 : 따옴표 및 / 또는 큰 따옴표를 이스케이프하거나 큰 따옴표로 묶어야합니다.
$ myfunc 'o "M' echo "My String"
String 'echo My String' don't contain substring: 'o "M'.
$ myfunc 'o "M' echo \"My String\"
String 'echo "My String"' contain substring: 'o "M'.
간단한 기능
이것은 BusyBox, Dash 및 Bash에서 테스트되었습니다.
stringContain() { [ -z "${2##*$1*}" ]; }
그런 다음 :
$ if stringContain 'o "M3' 'echo "My String"';then echo yes;else echo no;fi
no
$ if stringContain 'o "M' 'echo "My String"';then echo yes;else echo no;fi
yes
… 또는 @Sjlver가 지적한 것처럼 제출 된 문자열이 비어 있으면 함수는 다음과 같습니다.
stringContain() { [ -z "${2##*$1*}" ] && [ -z "$1" -o -n "$2" ]; }
또는 Adrian Günter의 의견 에서 제안한대로 -o
스위치를 피하십시오 .
stringContain() { [ -z "${2##*$1*}" ] && { [ -z "$1" ] || [ -n "$2" ];};}
최종 (간단한) 기능 :
그리고 테스트를 뒤집어 잠재적으로 더 빨리 만들 수 있습니다.
stringContain() { [ -z "$1" ] || { [ -z "${2##*$1*}" ] && [ -n "$2" ];};}
빈 문자열로 :
$ if stringContain '' ''; then echo yes; else echo no; fi
yes
$ if stringContain 'o "M' ''; then echo yes; else echo no; fi
no
대소 문자 구분 (Bash 만 해당)
대소 문자를 구분하지 않고 문자열을 테스트하려면 각 문자열을 소문자로 변환하십시오.
stringContain() {
local _lc=${2,,}
[ -z "$1" ] || { [ -z "${_lc##*${1,,}*}" ] && [ -n "$2" ] ;} ;}
검사:
stringContain 'o "M3' 'echo "my string"' && echo yes || echo no
no
stringContain 'o "My' 'echo "my string"' && echo yes || echo no
yes
if stringContain '' ''; then echo yes; else echo no; fi
yes
if stringContain 'o "M' ''; then echo yes; else echo no; fi
no
답변
쉘 스크립팅은 언어가 아니며 명령 모음에 가깝습니다. 본능적으로이 “언어”는if
a [
또는 a[[
. 둘 다 다른 명령과 마찬가지로 성공 또는 실패를 나타내는 종료 상태를 반환하는 명령 일뿐입니다. 이런 이유로 나는 명령을 사용 grep
하지 않고을 사용한다 [
.
그냥 해:
if grep -q foo <<<"$string"; then
echo "It's there"
fi
이제 당신이 생각하고 있습니다 if
명령 뒤에 나오는 명령의 종료 상태 (세미콜론으로 완료)를 테스트 있다면, 테스트중인 문자열의 소스를 다시 고려하지 않는 이유는 무엇입니까?
## Instead of this
filetype="$(file -b "$1")"
if grep -q "tar archive" <<<"$filetype"; then
#...
## Simply do this
if file -b "$1" | grep -q "tar archive"; then
#...
이 -q
옵션은 우리가 리턴 코드만을 원하기 때문에 grep이 아무것도 출력하지 않게합니다. <<<
쉘이 다음 단어를 확장하고 <<
여기 문서 의 한 줄 버전 인 명령에 대한 입력으로 사용합니다 (표준인지 Bashism인지 확실하지 않습니다).
답변
허용되는 답변이 가장 좋지만 여러 가지 방법이 있으므로 여기에 다른 해결책이 있습니다.
if [ "$string" != "${string/foo/}" ]; then
echo "It's there!"
fi
${var/search/replace}
인 $var
첫 번째 인스턴스 search
로 대체 replace
가 발견되면 (변경되지 않음 $var
). 당신은 대체하려고하면 foo
아무것도에 의해, 그리고 문자열이 변경된 후, 분명히 foo
발견되었다.
답변
따라서이 질문에 대한 유용한 솔루션이 많이 있지만 가장 빠르거나 가장 적은 리소스를 사용하는 솔루션은 무엇입니까?
이 프레임을 사용하여 반복 테스트 :
/usr/bin/time bash -c 'a=two;b=onetwothree; x=100000; while [ $x -gt 0 ]; do TEST ; x=$(($x-1)); done'
매번 테스트 교체 :
[[ $b =~ $a ]] 2.92 user 0.06 system 0:02.99 elapsed 99% CPU
[ "${b/$a//}" = "$b" ] 3.16 user 0.07 system 0:03.25 elapsed 99% CPU
[[ $b == *$a* ]] 1.85 user 0.04 system 0:01.90 elapsed 99% CPU
case $b in *$a):;;esac 1.80 user 0.02 system 0:01.83 elapsed 99% CPU
doContain $a $b 4.27 user 0.11 system 0:04.41 elapsed 99%CPU
(do는 F. Houri의 답변에 포함되었습니다)
그리고 낄낄 거림 :
echo $b|grep -q $a 12.68 user 30.86 system 3:42.40 elapsed 19% CPU !ouch!
따라서 간단한 대체 옵션은 연장 된 테스트 또는 사례에서 예측 가능합니다. 휴대용 케이스입니다.
100 만 그렙까지 배관하는 것은 예상치 못한 고통입니다! 필요없이 외부 유틸리티를 사용하는 것에 대한 기존의 규칙이 적용됩니다.