bash에서 문자열이 다른 문자열의 하위 문자열인지 확인하는 방법은 무엇입니까?


49

문자열이 다른 문자열 의 일부 안에 있는지 확인하고 싶습니다 .
예 :

'ab' in 'abc' -> true
'ab' in 'bcd' -> false

bash 스크립트 조건부에서 어떻게 할 수 있습니까?

답변:


27

당신은 형태로 사용할 수 있습니다 더 큰 문자열을 포함하고 당신을 찾기 위해 노력하는 하위 문자열입니다 :${VAR/subs}VARsubs

my_string=abc
substring=ab
if [ "${my_string/$substring}" = "$my_string" ] ; then
  echo "${substring} is not in ${my_string}"
else
  echo "${substring} was found in ${my_string}"
fi

이것은 문자열과 ${VAR/subs}동일 $VAR하지만 첫 번째로 나타나는 문자열이 subs제거 되었기 때문에 작동합니다 . 특히 $VAR단어가 포함되어 있지 않으면 subs수정되지 않습니다.


나는 당신이 echo진술 의 순서를 바꿔야한다고 생각합니다 . 내가 받기 때문에ab is not in abc
Lucio

당신이 맞아요! : P
edwin 2016 년

아니. 스크립트가 틀렸어. 그런 내가 얻을 수 ab was found in abc있지만, 내가 사용하는 경우 substring=z내가 얻을z was found in abc
루시오

1
이제 나는 얻는다 ab is not in abc. 그러나 z was found in abc. 재미있다 : D
Lucio

1
어이! 메아리는 이것의 시작에 맞았습니다! XD
edwin

47

[[ "bcd" =~ "ab" ]]
[[ "abc" =~ "ab" ]]

괄호는 테스트 용이며 이중 괄호이므로 다음과 같은 추가 테스트가 가능 =~합니다.

이 양식을 다음과 같이 사용할 수 있습니다.

var1="ab"
var2="bcd"
if [[ "$var2" =~ "$var1" ]]; then
    echo "pass"
else
    echo "fail"
fi

편집 : "= ~"수정, 뒤집 혔습니다.


1
나는 fail이 매개 변수들을 얻는다 :var2="abcd"
Lucio

3
@Lucio 맞습니다 [[ $string =~ $substring ]]. 나는 대답을 업데이트했다.
Eric Carvalho

12

bash 파일 이름 패턴 (일명 "글로브"패턴) 사용

substr=ab
[[ abc == *"$substr"* ]] && echo yes || echo no    # yes
[[ bcd == *"$substr"* ]] && echo yes || echo no    # no

만약 [[ "$ JAVA_OPTS"! = "-XX : + UseCompressedOops" ]] ;; 그런 다음 JAVA_OPTS = "$ JAVA_OPTS -XX : + UseCompressedOops"를 내 보냅니다.; fi
Mike Slinn

10

다음 두 가지 접근 방식은 bash뿐만 아니라 모든 POSIX 호환 환경에서 작동합니다.

substr=ab
for s in abc bcd; do
    if case ${s} in *"${substr}"*) true;; *) false;; esac; then
        printf %s\\n "'${s}' contains '${substr}'"
    else
        printf %s\\n "'${s}' does not contain '${substr}'"
    fi
done
substr=ab
for s in abc bcd; do
    if printf %s\\n "${s}" | grep -qF "${substr}"; then
        printf %s\\n "'${s}' contains '${substr}'"
    else
        printf %s\\n "'${s}' does not contain '${substr}'"
    fi
done

위 출력 모두 :

'abc' contains 'ab'
'bcd' does not contain 'ab'

전자는 별도의 grep프로세스를 생성하지 않는 이점이 있습니다.

백 슬래시가 포함되어 있으면 맹 글링 할 수 있기 때문에 printf %s\\n "${foo}"대신에 사용하십시오 .echo "${foo}"echo${foo}


첫 번째 버전은 xrandr변수에 저장된 모니터 이름 목록에서 모니터 이름 의 하위 문자열을 찾는 데 완벽하게 작동 합니다. +1 및 1K 담당자 클럽에 오신 것을 환영합니다 :)
WinEunuuchs2Unix

6

쉘 사례 진술

이것은 가장 휴대용 솔루션이며 오래된 Bourne 쉘 및 Korn 쉘에서도 작동합니다.

#!/bin/bash
case "abcd" in
    *$1*) echo "It's a substring" ;;
    *) echo "Not a substring" ;;
esac

샘플 실행 :

$ ./case_substr.sh "ab"                                                                                           
It's a substring
$ ./case_substr.sh "whatever"                                                                                     
Not a substring

구체적으로 사용할 필요는 없으며 성공 또는 실패를 echo사용 exit 1하고 exit 0나타낼 수 있습니다 .

우리가 할 수있는 일은 특정 반환 값 (일치하는 0, 일치하지 않는 1)을 가진 함수 (필요한 경우 큰 스크립트에서 사용할 수 있음)를 만드는 것입니다.

$ ./substring_function.sh                                  
ab is substring

$ cat substring_function.sh                                
#!/bin/sh

is_substring(){
    case "$2" in
        *$1*) return 0;;
        *) return 1;;
    esac
}

main(){
   if is_substring "ab" "abcdefg"
   then
       echo "ab is substring"
   fi
}

main $@

grep

$ grep -q 'ab' <<< "abcd" && echo "it's a substring" || echo "not a substring"                                    
it's a substring

이 특정 방법은의 if-else 문에 유용합니다 bash. 또한 대부분 휴대용

AWK

$ awk '$0~/ab/{print "it is a substring"}' <<< "abcd"                                                             
it is a substring

파이썬

$ python -c 'import sys;sys.stdout.write("it is a substring") if "ab" in sys.stdin.read() else exit(1)' <<< "abcd"
it is a substring

루비

$ ruby -e ' puts "is substring" if  ARGV[1].include? ARGV[0]'  "ab" "abcdef"                                             
is substring

다른 모든 사람을 넘어서서 +1. 여기 및 다른 스택 교환 사이트에서 문자열 내 하위 문자열의 오프셋을 반환하는 응답이 없습니다. 오늘 밤의 임무는 :)
WinEunuuchs2Unix

@ WinEunuuchs2Unix bash에서 그렇게 하시겠습니까?
Sergiy Kolodyazhnyy

예, 아니요. 저는 파이썬이 gmail.com 메시지 메타 데이터를 모두 가져오고 bash가 구문 분석하고 GUI 목록을 드릴 다운하는 Frankenstein 프로젝트를 수행하고 있습니다. 나는 여기에 대답을 찾았습니다 : stackoverflow.com/questions/5031764/…
WinEunuuchs2Unix

@ WinEunuuchs2Unix OK. 흥미로운 것 같습니다. 개인적으로 파이썬으로 모든 것을 파싱하는 것을 선호합니다. bash 단독보다 텍스트 처리 기능이 훨씬 많습니다.
Sergiy Kolodyazhnyy

나는 약 2 년 동안 당신의 선호를 알고 그것을 존중합니다. 그러나 나는 단지 파이썬을 배우고 그 안에서 일하기를 힘들게하는 것은 나에게 번거로운 것 같습니다. bash에서 이미 익숙한 모든 배열 처리는 말할 것도 없습니다. 하지만 적어도 첫 번째 파이썬 스크립트를 작성하여 Google의 gmail.com에서 Linux 플랫 파일로 모든 것을 빨아 들입니까? :)
WinEunuuchs2Unix

5

마음 [[":

[[ $a == z* ]]   # True if $a starts with an "z" (pattern matching).
[[ $a == "z*" ]] # True if $a is equal to z* (literal matching).

[ $a == z* ]     # File globbing and word splitting take place.
[ "$a" == "z*" ] # True if $a is equal to z* (literal matching).

@glenn_jackman이 말했듯이 두 번째 전체 용어를 큰 따옴표로 묶으면 테스트가 리터럴 일치로 전환됩니다 .

출처 : http://tldp.org/LDP/abs/html/comparison-ops.html


4

edwin의 답변과 비슷하지만 posix & ksh의 이식성이 향상되었으며 Richard의 것보다 시끄럽지 않은 터치가 있습니다.

substring=ab

string=abc
if [ "$string" != "${string%$substring*}" ]; then
    echo "$substring IS in $string"
else
    echo "$substring is NOT in $string"
fi

string=bcd
if [ "$string" != "${string%$substring*}" ]; then
    echo "$string contains $substring"
else
    echo "$string does NOT contain $substring"
fi

산출:

abc contains ab
bcd does NOT contain ab
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.