Bash에서 문자열에 하위 문자열이 포함되어 있는지 확인하는 방법


2565

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

약간 서투른 것 같습니다.


4
빈 문자열이 잘못된 경우 왜 서투른 것으로 간주합니까? 제안 된 솔루션에도 불구하고 나를 위해 일한 유일한 방법이었습니다.
ericson.cepeda

1
expr여기서 명령을 사용할 수 있습니다
cli__

4
posix 포탄을위한 것입니다 : stackoverflow.com/questions/2829613/…
sehe

답변:


3649

당신은 사용할 수 있습니다 마커스의 대답 (* 와일드 카드)를 사용하면 이중 괄호를 사용하는 경우도 case 문 밖에서 :

string='My long string'
if [[ $string == *"My long"* ]]; then
  echo "It's there!"
fi

needle string의 공백은 큰 따옴표로 묶어야하며 *와일드 카드는 외부에 있어야합니다. 또한 ==정규 비교 연산자가 아닌 간단한 비교 연산자가 사용됩니다 =~.


127
또한 테스트에서! =로 전환하여 비교를 되돌릴 수 있습니다. 답변 해주셔서 감사합니다!
Quinn Taylor

63
@Jonik : shebang이 없거나로있을 수 있습니다 #!/bin/sh. #!/bin/bash대신 시도하십시오 .
추후 공지가있을 때까지 일시 중지되었습니다.

10
대괄호와 내용 사이에 공백을 두십시오.
Paul Price

17
[[]] 안에 변수를 인용 할 필요는 없습니다. [[$ string == $ needle ]] && echo found
Orwellophile

12
@Orwellophile 조심해! 의 첫 번째 인수에서 큰 따옴표 만 생략 할 수 있습니다 [[. 참조 ideone.com/ZSy1gZ
nyuszika7h

611

정규식 접근 방식을 선호하는 경우 :

string='My string';

if [[ $string =~ "My" ]]
then
   echo "It's there!"
fi

2
bash 스크립트에서 egrep 정규 표현식을 대체해야했지만 이것은 완벽하게 작동했습니다!
blast_hardcheese

114
=~운영자는 이미 경기를 위해 전체 문자열을 검색; 의 .*는 이질적입니다. 또한 따옴표는 일반적으로 백 슬래시보다 선호됩니다.[[ $string =~ "My s" ]]
bukzor

16
@bukzor Quotes는 Bash 3.2+부터 tiswww.case.edu/php/chet/bash/FAQ에서 작동을 멈췄 습니다 E14) . 변수에 따옴표를 사용하여 할당 한 다음 비교하는 것이 가장 좋습니다. : 이것처럼re="My s"; if [[ $string =~ $re ]]
seanf

36
문자열을 포함 하지 않는지 테스트하십시오 : if [[ ! "abc" =~ "d" ]]true.
KrisWebDev

1
테스트 순서는 중요합니다. 다음 코드 줄의 출력은 앞으로 2 될 것입니다number=2; if [[ "1, 2, 4, 5" = *${number}* ]]; then echo forward $number; fi; if [[ *${number}* = "1, 2, 4, 5" ]]; then echo backwards $number; fi;
데르 Leest Douwe 반

356

if 문을 사용할지는 확실하지 않지만 case 문을 사용하면 비슷한 효과를 얻을 수 있습니다.

case "$string" in 
  *foo*)
    # Do stuff
    ;;
esac

76
posix 쉘에 이식 가능하므로 이것은 아마도 최상의 솔루션 일 것입니다. (일명 bashisms)
technosaurus

25
@technosaurus 나는 배쉬 태그 만있는 질문에서 "bashism"을 비판하는 것이 다소 이상하다고 생각한다. :)
PP

39
@PP 더 제한적인 솔루션보다 더 보편적 인 솔루션을 선호한다는 것은 비판이 아닙니다. 몇 년 후, 나와 같은 사람들이이 답변을 찾기 위해 들러서 원래 질문보다 더 넓은 범위에서 유용한 답변을 찾을 수 있다는 것을 고려하십시오. 그들이 오픈 소스 세계에서 말하는 것처럼 : "선택은 좋다!"
Carl Smotricz

2
@technosaurus, FWIW [[ $string == *foo* ]]는 일부 POSIX 호환 sh 버전 (예 : /usr/xpg4/bin/shSolaris 10) 및 ksh (> = 88)에서도 작동합니다.
maxschlepzig

3
Busybox ash는 별표를 처리하지 않습니다 [[... 케이스 스위치가 작동했습니다!
Ray Foss

232

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

1
함수에 넣는 방법을 알아낼 수 있다면 훨씬 더 좋습니다.
Eero Aaltonen

2
@EeroAaltonen 내 (새로 추가 된) 기능을 어떻게 찾습니까?
F. Hauri

2
알아! 찾기 . 이름 "*"| xargs grep "myfunc"2> ​​/ dev / null
eggmatters

6
호환성이 뛰어 나기 때문에 훌륭합니다. 그러나 하나의 버그 : 건초 더미 문자열이 비어 있으면 작동하지 않습니다. 올바른 버전은 string_contains() { [ -z "${2##*$1*}" ] && [ -n "$2" -o -z "$1" ]; } 최종 생각입니다. 빈 문자열에 빈 문자열이 포함되어 있습니까? 위의 버전은 그렇습니다 ( -o -z "$1"부분 때문에 ).
Sjlver

3
+1. 아주 좋아요! 나를 위해 order stringContain () {[-z "$ {1 ## * $ 2 *}"] && [-z "$ 2"-o -n "$ 1"]; }; "어디 검색" "무엇을 찾으십시오". busybox에서 작업하십시오. busybox에서는 위의 답변이 작동하지 않습니다.
user3439968

148

쉘 스크립팅은 언어가 아니며 명령 모음에 가깝습니다. 본능적으로이 "언어"는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인지 확실하지 않습니다).


7
그들 불리는 문자열 (3.6.7) 여기서 나는 그것이 bashism 믿는다
alex.pilon

10
프로세스 대체를 사용할 수도 있습니다if grep -q foo <(echo somefoothing); then
larsr December

참고 echo당신은 변수를 전달하는 경우 인자를 취하지되고, 사용 printf '%s' "$string대신.
nyuszika7 시간

5
이것의 비용은 매우 비싸다 : grep -q foo <<<"$mystring"1 포크를 내포 하고 echo $mystring | grep -q foobashism이고 2 포크를 내포한다 (파이프를위한 것과 다른 것을위한 것 /path/to/grep)
F. Hauri

1
echo인수 문자열에 백 슬래시 시퀀스가 ​​포함되어 있으면 플래그가없는 @BrunoBronosky에 여전히 예기치 않은 이식성 문제가있을 수 있습니다. echo "nope\c"일부 플랫폼 echo -e "nope"에서는 다른 플랫폼과 같이 작동 할 것으로 예상됩니다 . printf '%s' "nope"vsprintf '%s\n' 'nope\c'
tripleee

92

허용되는 답변이 가장 좋지만 여러 가지 방법이 있으므로 여기에 다른 해결책이 있습니다.

if [ "$string" != "${string/foo/}" ]; then
    echo "It's there!"
fi

${var/search/replace}$var첫 번째 인스턴스 search로 대체 replace가 발견되면 (변경되지 않음 $var). 당신은 대체하려고하면 foo아무것도에 의해, 그리고 문자열이 변경된 후, 분명히 foo발견되었다.


5
위의 ephemient의 솔루션 :>`if [ "$ string"! = "$ {string / foo /}"]; "반갑습니다!" fi`는 BusyBox의 쉘 애쉬를 사용할 때 유용합니다 . 일부 bash의 정규 표현식이 구현되지 않았기 때문에 수락 된 솔루션이 BusyBox에서 작동하지 않습니다.
TPoschel

1
차이의 불평등. 꽤 이상한 생각! 나는 그것을 좋아한다
nitinr708

1
문자열이 'foo'가 아닌 한
venimus

나는이 동일한 솔루션을 직접 작성했으며 (통역사가 최고의 답변을 얻지 못했기 때문에) 더 나은 솔루션을 찾고 있었지만 이것을 찾았습니다!
BuvinJ

56

따라서이 질문에 대한 유용한 솔루션이 많이 있지만 가장 빠르거나 가장 적은 리소스를 사용하는 솔루션은 무엇입니까?

이 프레임을 사용하여 반복 테스트 :

/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 만 그렙까지 배관하는 것은 예상치 못한 고통입니다! 필요없이 외부 유틸리티를 사용하는 것에 대한 기존의 규칙이 적용됩니다.


4
깔끔한 벤치 마크. 내가 사용하도록 설득했다 [[ $b == *$a* ]].
미친 물리학 자

2
이것을 올바르게 읽으면 case가장 작은 전체 시간 소비로 승리합니다. $b in *$a그래도 별표가 없습니다 . 버그가 수정 된 [[ $b == *$a* ]]것보다 약간 더 빠른 결과를 얻지 case만 물론 다른 요소에도 의존 할 수 있습니다.
tripleee

1
ideone.com/5roEVt 는 수정 된 추가 버그에 대한 실험을하고 다른 시나리오 (문자열이 실제로 더 긴 문자열에없는 경우)에 대한 테스트를 수행했습니다. 결과는 대체로 비슷합니다. [[ $b == *$a* ]]빠르고 빠르며 casePOSIX 호환 가능합니다.
tripleee

28

이것은 또한 작동합니다 :

if printf -- '%s' "$haystack" | egrep -q -- "$needle"
then
  printf "Found needle in haystack"
fi

그리고 부정적인 테스트는 다음과 같습니다.

if ! printf -- '%s' "$haystack" | egrep -q -- "$needle"
then
  echo "Did not find needle in haystack"
fi

이 스타일은 조금 더 고전적이며 Bash 쉘의 기능에 덜 의존적이라고 생각합니다.

--인수는 다음과 같은 옵션과 유사한 입력 문자열에 대해 보호에 사용되는 순수 POSIX의 편집증이다 --abc-a.

참고 : 긴밀한 루프에서이 코드는 내부 Bash 쉘 기능을 사용하는 것보다 훨씬 느립니다. 하나 또는 두 개의 개별 프로세스가 파이프를 통해 작성되고 연결되기 때문입니다.


5
...하지만 OP는 어떤 버전 의 bash를 말하지 않습니다 . 예를 들어, 솔라리스와 같이 오래된 bash에는 이러한 새로운 bash 기능이 포함되어 있지 않을 수 있습니다. (나는 bash 2.0이있는 solaris 에서이 정확한 문제 (bash 패턴 일치가 구현되지 않음)를 경험했다)
michael

2
echo휴대 할 수 없으므로 printf '%s' "$haystack대신 사용해야합니다 .
nyuszika7 시간

2
아니, 그냥로 echo시작하지 않는 이스케이프가없는 리터럴 텍스트 이외의 모든 것을 피 하십시오 -. 그것은 당신을 위해 작동 할 수 있지만 휴대용이 아닙니다. 옵션 설정 echo여부에 따라 bash조차도 다르게 동작합니다 xpg_echo. 추신 : 이전 의견에서 큰 따옴표를 닫는 것을 잊었습니다.
nyuszika7 시간

1
@kevinarpe 확실 --하지 않습니다에 대한 POSIX 사양에printf 나열되어 있지 않지만 문자 printf '%s' "$anything"$anything포함 된 경우 문제를 피 하려면 어쨌든 사용해야 합니다 %.
nyuszika7h

1
@kevinarpe 아마도 그것은 아마입니다.
nyuszika7 시간

21

배쉬 4+ 예제. 참고 : 따옴표를 사용하지 않으면 단어에 공백 등이 포함 된 경우 문제가 발생할 수 있습니다. 항상 Bash, IMO로 인용하십시오.

Bash 4+의 예는 다음과 같습니다.

예제 1, 문자열에서 'yes'를 확인하십시오 (대소 문자 구분).

    if [[ "${str,,}" == *"yes"* ]] ;then

예제 2, 문자열에서 'yes'를 확인하십시오 (대소 문자 구분).

    if [[ "$(echo "$str" | tr '[:upper:]' '[:lower:]')" == *"yes"* ]] ;then

예제 3, 문자열에서 'yes'를 확인하십시오 (대소 문자 구분).

     if [[ "${str}" == *"yes"* ]] ;then

예제 4, 문자열에서 'yes'를 확인하십시오 (대소 문자 구분).

     if [[ "${str}" =~ "yes" ]] ;then

예 5, 정확히 일치 (대소 문자 구분) :

     if [[ "${str}" == "yes" ]] ;then

예 6, 정확히 일치 (대소 문자 구분) :

     if [[ "${str,,}" == "yes" ]] ;then

예제 7, 정확히 일치하는 내용 :

     if [ "$a" = "$b" ] ;then

예 8, 와일드 카드 일치 .ext (대소 문자 구분) :

     if echo "$a" | egrep -iq "\.(mp[3-4]|txt|css|jpg|png)" ; then

즐겨.


17

이건 어때요:

text="   <tag>bmnmn</tag>  "
if [[ "$text" =~ "<tag>" ]]; then
   echo "matched"
else
   echo "not matched"
fi

2
= ~는 정규식 일치를위한 것이므로 OP의 목적에는 너무 강력합니다.

16

Paul 이 그의 성능 비교에서 언급 한 것처럼 :

if echo "abcdefg" | grep -q "bcdef"; then
    echo "String contains is true."
else
    echo "String contains is not true."
fi

이것은 Marcus가 제공 한 답변 의 'case "$ string"과 같은 POSIX 호환 이지만 case statement 답변보다 읽기 쉽습니다. 또한 case 문을 사용하는 것보다 훨씬 느릴 것입니다. Paul이 지적했듯이 루프에서 사용하지 마십시오.



9
[[ $string == *foo* ]] && echo "It's there" || echo "Couldn't find"

echo "Couldn't find끝에 있는 명령문은 이러한 일치하는 명령에 대해 0 종료 상태를 반환하는 좋은 방법입니다.
nicodjimenez

@nicodjimenez이 솔루션으로는 더 이상 종료 상태를 타겟팅 할 수 없습니다. 종료 상태는 상태 메시지에 의해 삼켜집니다.
Jahid

1
정확히 내가 의미하는 바입니다 ... || echo "Couldn't find"없으면 일치하지 않는 경우 오류 종료 상태를 반환합니다. 예를 들어 모든 명령을 반환하려는 CI 파이프 라인을 실행하는 경우 원하지 않을 수 있습니다 비 오류 종료 상태
nicodjimenez

9

하나는:

[ $(expr $mystring : ".*${search}.*") -ne 0 ] && echo 'yes' ||  echo 'no'

2
exprswiss-army-knife 유틸리티 중 하나는 일반적으로 필요한 작업을 수행 할 수있는 방법 중 하나입니다. 일단 수행 방법을 알아 낸 후에는 구현 한 후에는 왜 또는 어떻게 수행하고 있는지 기억할 수 없으므로 다시는 손대지 말고 그 일을 멈추지 않기를 바랍니다.
마이클

@AloisMahdal 나는 결코 투표를하지 않았다. 나는 왜 downvotes가 주어지는지를 가정하고있다. 주의 의견. 나는 expr이식성이 bash (예를 들어, 이전 버전에서 일관성이없는 동작), tr (모든 곳에서 일관성이 없음) 또는 sed (때로는 너무 느림) 사용을 방해하는 드문 경우에 사용합니다. 그러나 개인적인 경험을 통해 이러한 expr사상을 다시 읽을 때마다 맨 페이지로 돌아 가야합니다. 그래서, 나는 단지 모든 사용법이 논평된다고 언급하고 싶습니다 expr.
michael

1
당신이 가진 모든 것이 원래 Bourne 껍질이었습니다. 이 도구 같은 일부 공통적으로 필요한 기능이 부족 expr하고 test이를 수행하기 위해 구현되었다. 이 시대에는 일반적으로 더 나은 도구가 있으며 대부분은 현대식 껍질에 내장되어 있습니다. 나는 test아직도 거기에 매달려 있다고 생각 하지만, 아무도 빠진 것 같지 expr않습니다.
tripleee

6

나는 sed를 좋아한다.

substr="foo"
nonsub="$(echo "$string" | sed "s/$substr//")"
hassub=0 ; [ "$string" != "$nonsub" ] && hassub=1

편집, 논리 :

  • sed를 사용하여 문자열에서 부분 문자열 인스턴스 제거

  • 새 문자열이 이전 문자열과 다른 경우 하위 문자열이 존재합니다


2
설명을 추가하십시오.
Zulan

5

grep -q 이 목적에 유용합니다.

같은 사용 awk:

string="unix-bash 2389"
character="@"
printf '%s' "$string" | awk -vc="$character" '{ if (gsub(c, "")) { print "Found" } else { print "Not Found" } }'

산출:

찾을 수 없음

string="unix-bash 2389"
character="-"
printf '%s' "$string" | awk -vc="$character" '{ if (gsub(c, "")) { print "Found" } else { print "Not Found" } }'

산출:

녹이다

원본 출처 : http://unstableme.blogspot.com/2008/06/bash-search-letter-in-string-awk.html


3
echo휴대 할 수 없으므로 printf '%s' "$string"대신 사용해야합니다 . 사용자가 더 이상 존재하지 않기 때문에 답변을 편집하고 있습니다.
nyuszika7 시간

echo@ nyuszika7h 는 어떤 식으로 이식성이 없습니까?
starbeamrainbowlabs

5

이 기능이 자주 필요하다는 것을 알았습니다. 따라서 필자 .bashrc가 기억하기 쉬운 이름으로 필요할 때마다 재사용 할 수 있는 홈 셸 기능을 사용하고 있습니다.

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

$string1(예를 들어, abc )가 $string2(예를 들어, 123abcABC )에 포함되어 있는지 테스트하려면 stringinstring "$string1" "$string2"반환 값을 확인 하고 실행 하면됩니다.

stringinstring "$str1" "$str2"  &&  echo YES  ||  echo NO

[[ "$ str"== $ substr ]] && 에코 예 || echo NO
elyase

나는 x핵이 아주 오래된 껍질 에만 필요하다고 확신합니다 .
nyuszika7 시간

5

.bash_profile 파일 및 grep 사용 방법 :

PATH 환경 변수에 두 개의 bin디렉토리가 포함되어 있으면 추가하지 마십시오.

# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi

U=~/.local.bin:~/bin

if ! echo "$PATH" | grep -q "home"; then
    export PATH=$PATH:${U}
fi

1
이것이 답입니까?
codeforester

공감. grep이 훨씬 강력 할 때 Bash가 어떻게 사용할 수 있는지 배워야하는 이유는 무엇입니까? 또한 패턴 목록과 일치시켜 조금 더 확장하십시오 grep -q -E 'pattern1|...|patternN'.
Mohamed Bana

4

문제의 확장 답이 여기에 어떻게 문자열 POSIX 쉬에 다른 문자열을 포함하는 경우 알 수 있습니까?:

이 솔루션은 특수 문자와 함께 작동합니다.

# contains(string, substring)
#
# Returns 0 if the specified string contains the specified substring,
# otherwise returns 1.
contains() {
    string="$1"
    substring="$2"

    if echo "$string" | $(type -p ggrep grep | head -1) -F -- "$substring" >/dev/null; then
        return 0    # $substring is in $string
    else
        return 1    # $substring is not in $string
    fi
}

contains "abcd" "e" || echo "abcd does not contain e"
contains "abcd" "ab" && echo "abcd contains ab"
contains "abcd" "bc" && echo "abcd contains bc"
contains "abcd" "cd" && echo "abcd contains cd"
contains "abcd" "abcd" && echo "abcd contains abcd"
contains "" "" && echo "empty string contains empty string"
contains "a" "" && echo "a contains empty string"
contains "" "a" || echo "empty string does not contain a"
contains "abcd efgh" "cd ef" && echo "abcd efgh contains cd ef"
contains "abcd efgh" " " && echo "abcd efgh contains a space"

contains "abcd [efg] hij" "[efg]" && echo "abcd [efg] hij contains [efg]"
contains "abcd [efg] hij" "[effg]" || echo "abcd [efg] hij does not contain [effg]"

contains "abcd *efg* hij" "*efg*" && echo "abcd *efg* hij contains *efg*"
contains "abcd *efg* hij" "d *efg* h" && echo "abcd *efg* hij contains d *efg* h"
contains "abcd *efg* hij" "*effg*" || echo "abcd *efg* hij does not contain *effg*"

이 옵션은 옵션으로 삼킬 contains "-n" "n"것이기 때문에 여기서 작동하지 않습니다 ! 그에 대한 인기있는 수정은 대신 사용하는 것입니다. echo -n-nprintf "%s\n" "$string"
joeytwiddle

완벽하게 해결 된 문자열 포함 공간
dengApro

4

때문에 POSIX / 비지 박스 질문은 정답 (IMHO)를 제공하지 않고 폐쇄, 여기에 대한 답변을 게시합니다.

가능한 가장 짧은 대답은 다음과 같습니다.

[ ${_string_##*$_substring_*} ] || echo Substring found!

또는

[ "${_string_##*$_substring_*}" ] || echo 'Substring found!'

점을 유의 이중 해시 입니다 의무 몇 가지 껍질 ( ash). 위 [ stringvalue ]의 부분 문자열을 찾을 수 없을 때 평가 합니다. 오류를 반환하지 않습니다. 부분 문자열이 발견되면 결과가 비어 있고 평가 [ ]됩니다. 문자열이 완전히 대체되기 때문에 (오류로 인해 *) 오류 코드 1이 발생합니다 .

가장 짧은 가장 일반적인 구문 :

[ -z "${_string_##*$_substring_*}" ] && echo 'Substring found!'

또는

[ -n "${_string_##*$_substring_*}" ] || echo 'Substring found!'

다른 것:

[ "${_string_##$_substring_}" != "$_string_" ] && echo 'Substring found!'

또는

[ "${_string_##$_substring_}" = "$_string_" ] || echo 'Substring found!'

단일 등호를 참고 하십시오!


3

정확한 단어 일치 :

string='My long string'
exactSearch='long'

if grep -E -q "\b${exactSearch}\b" <<<${string} >/dev/null 2>&1
  then
    echo "It's there"
  fi

3

oobash를 사용해보십시오.

Bash 4를위한 OO 스타일 문자열 라이브러리입니다. 독일 움라우트를 지원합니다. Bash로 작성되었습니다.

많은 기능을 이용하실 수 있습니다 : -base64Decode, -base64Encode, -capitalize, -center, -charAt, -concat, -contains, -count, -endsWith, -equals, -equalsIgnoreCase, -reverse, -hashCode, -indexOf, -isAlnum, -isAlpha, -isAscii, -isDigit, -isEmpty, -isHexDigit, -isLowerCase, -isSpace, -isPrintable, -isUpperCase, -isVisible, -lastIndexOf, -length, -matches, -replaceAll, -replaceFirst, -startsWith, -substring, -swapCase, -toLowerCase, -toString, -toUpperCase, -trim,와 -zfill.

상기 봐가 포함 예 :

[Desktop]$ String a testXccc
[Desktop]$ a.contains tX
true
[Desktop]$ a.contains XtX
false

oobash는 Sourceforge.net에서 사용 가능 합니다.


2

나는이 기능을 사용한다 (하나의 의존성은 포함되어 있지 않지만 명백하다). 아래에 표시된 테스트를 통과합니다. 함수가 0보다 큰 값을 반환하면 문자열이 발견 된 것입니다. 대신 1 또는 0을 쉽게 반환 할 수 있습니다.

function str_instr {
   # Return position of ```str``` within ```string```.
   # >>> str_instr "str" "string"
   # str: String to search for.
   # string: String to search.
   typeset str string x
   # Behavior here is not the same in bash vs ksh unless we escape special characters.
   str="$(str_escape_special_characters "${1}")"
   string="${2}"
   x="${string%%$str*}"
   if [[ "${x}" != "${string}" ]]; then
      echo "${#x} + 1" | bc -l
   else
      echo 0
   fi
}

function test_str_instr {
   str_instr "(" "'foo@host (dev,web)'" | assert_eq 11
   str_instr ")" "'foo@host (dev,web)'" | assert_eq 19
   str_instr "[" "'foo@host [dev,web]'" | assert_eq 11
   str_instr "]" "'foo@host [dev,web]'" | assert_eq 19
   str_instr "a" "abc" | assert_eq 1
   str_instr "z" "abc" | assert_eq 0
   str_instr "Eggs" "Green Eggs And Ham" | assert_eq 7
   str_instr "a" "" | assert_eq 0
   str_instr "" "" | assert_eq 0
   str_instr " " "Green Eggs" | assert_eq 6
   str_instr " " " Green "  | assert_eq 1
}

서스펜스! 의존성 무엇입니까 ?
Peter Mortensen

"str_escape_special_characters"기능 GitHub arcshell_str.sh 파일에 있습니다. arcshell.io가 당신을 데려다 줄 것입니다.
Ethan Post


0
msg="message"

function check {
    echo $msg | egrep [abc] 1> /dev/null

    if [ $? -ne 1 ];
    then 
        echo "found" 
    else 
        echo "not found" 
    fi
}

check

이것은 a 또는 b 또는 c의 발생을 찾을 것입니다


0

일반적인 바늘 건초 더미 예제는 변수를 따릅니다.

#!/bin/bash

needle="a_needle"
haystack="a_needle another_needle a_third_needle"
if [[ $haystack == *"$needle"* ]]; then
    echo "needle found"
else
    echo "needle NOT found"
fi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.