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.