Bash에서 문자열을 비교하는 방법


답변:


1372

if 문에서 변수 사용

if [ "$x" = "valid" ]; then
  echo "x has the value 'valid'"
fi

당신이 일치하지 않는 무언가를 할 경우, 교체 =와 함께 !=. 문자열 연산산술 연산 에 대한 자세한 내용은 해당 설명서를 참조하십시오.

왜 우리는 따옴표를 사용 $x합니까?

따옴표 $x가 비어 있으면 Bash 스크립트에 아래와 같이 구문 오류가 발생하기 때문에 따옴표를 원합니다 .

if [ = "valid" ]; then

==운영자의 비표준 사용

Bash는와 ==동등하게 사용될 수 [있지만 이것은 표준이 아니다 .

따옴표 $x가 선택적인 첫 번째 경우를 사용하십시오 .

if [[ "$x" == "valid" ]]; then

또는 두 번째 경우를 사용하십시오.

if [ "$x" = "valid" ]; then

12
예상치 못한 연산자 오류에 제공된 허용 된 답변과 어떤 관련이 있습니까? 를 사용할 때 같은 오류가 발생했습니다 [ "$1" == "on" ]. 이것을 ""$ 1 "="on "]으로 변경하면 문제가 해결되었습니다.
Piotr Dobrogost

78
공간이 필요합니다.
TAAPSogeking

6
@JohnFeminella bash 스크립트로 작성할 때 하나 =가 아닌 두 개가 있어야합니다 .
user13107

72
사용할 수 없다는 점에 주목할 가치가 있습니다 [ $x -eq "valid" ]. -eq문자열이 아닌 정수에 대한 비교 연산자입니다.
craq

2
@Alex, 어느 경우 에나 패턴을 사용해야하는 ["x$yes" == "xyes"]경우에는 변수와 문자열 리터럴 모두 앞에 x? 그것은 옛날의 유물입니까, 아니면 어떤 상황에서는 정말로 필요한가요?
lanoxx

142

또는 else 절이 필요하지 않은 경우 :

[ "$x" == "valid" ] && echo "x has the value 'valid'"

71
else 절이 필요하고 미친 원 라이너를 만들려면 [ "$ x"== "valid"] && echo "valid"|| 에코 "유효하지
Matt White

11
@MattWhite : 이것은 일반적으로 나쁜 생각 echo입니다. 실패 할 수 있습니다.
gniourf_gniourf

1
marko && MattWhite
Deko

3
@gniourf_gniourf, 문제 없습니다, 사용하십시오 [ "$X" == "valid" ] || ( echo invalid && false ) && echo "valid" .
12431234123412341234123

4
@ 12431234123412341234123 { echo invalid && false; }( echo invalid && false )불필요한 서브 쉘에 대한 비용을 지불하지 않기 때문에 보다 효율적 입니다.
Charles Duffy

84
a="abc"
b="def"

# Equality Comparison
if [ "$a" == "$b" ]; then
    echo "Strings match"
else
    echo "Strings don't match"
fi

# Lexicographic (greater than, less than) comparison.
if [ "$a" \< "$b" ]; then
    echo "$a is lexicographically smaller then $b"
elif [ "$a" \> "$b" ]; then
    echo "$b is lexicographically smaller than $a"
else
    echo "Strings are equal"
fi

노트:

  1. 사이의 공백 if[]중요하다
  2. ><리디렉션 연산자 그래서 그것을 탈출 있습니다 \>\<각각 문자열.

6
문자열 알파벳 순서를 비교해 주셔서 감사합니다
shadi

내 문제는 $a실제로 " "문자열 리터럴 값의 일부로 그것을 둘러싼 것이므로 이스케이프 문자를 사용 $b하여 값을 비교해야했습니다. 실행 한 후에 이것을 찾을 수있었습니다 bash -x ./script.sh.-x 플래그를 사용하면 각 실행 값을 볼 수 있으며 디버깅에 도움이됩니다.
ShahNewazKhan

알파벳 순서 비교는 POSIX 표준이 아니므로 GNU 이외의 플랫폼 / 비 bash 쉘에서는 작동하지 않을 수 있습니다. pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html 의 작업 만 이식 가능합니다.
찰스 더피

62

문자열을 와일드 카드와 비교하려면

if [[ "$stringA" == *$stringB* ]]; then
  # Do something here
else
  # Do Something here
fi

12
와일드 카드는 오른쪽에서만 사용할 수 있어야합니다! 또한 "와일드 카드 주위 에 누락 된 부분이 있습니다. (btw : 와일드 카드 +1!)
Scz

6
확장 $stringB 따옴표로 묶어야합니다 (실수로 왼쪽을 따옴표로 묶을 필요는 없습니다) : if [[ $stringA = *"$stringB"* ]]; then.
gniourf_gniourf

파일 경로에서 파일 이름에 동일한 와일드 카드 논리를 사용하려고합니다. 그러나 그것은 나를 위해 작동하지 않습니다. 여기에 제공된 모든 다른 와일드 카드 문자열을 사용해보십시오. 그러나 그것은 항상 다른 경우에 간다. 필자의 경우 stringA는 파일 경로 / tmp / file이고 stringB는 "file"입니다.

35

한 의견에서 의견 중 하나에 동의하지 않아야합니다.

[ "$x" == "valid" ] && echo "valid" || echo "invalid"

아니, 그건 미친 사람이 아니야

그것은 시작되지 않은 사람처럼 보입니다.

어떤 방식으로 공통 패턴을 언어로 사용합니다.

그리고 당신은 언어를 배운 후에.

실제로, 읽기 좋네요

논리 연산자의 지연 평가와 같은 특별한 부분을 가진 간단한 논리식입니다.

[ "$x" == "valid" ] && echo "valid" || echo "invalid"

각 부분은 논리적 표현입니다. 첫 번째는 참 또는 거짓 일 수 있고, 다른 두 가지는 항상 참입니다.

(
[ "$x" == "valid" ] 
&&
echo "valid"
)
||
echo "invalid"

이제 평가 될 때 첫 번째가 확인됩니다. 이 논리의 두 번째 피연산자보다, false 인 경우 && 후에는 관련이 없습니다. 첫 번째는 사실이 아니므로 첫 번째가 될 수 없으며 두 번째는 사실이 될 수 없습니다.
이제이 경우 논리의 첫 번째면 이거나 || 거짓이지만 다른면 (세 번째 부분)이 참이면 사실 일 수 있습니다.

따라서 세 번째 부분은 주로 부작용으로 메시지를 작성하여 평가됩니다. ( 0실제 결과 는 여기에서 사용하지 않습니다)

다른 경우도 비슷하지만 더 간단합니다. 약속합니다! 쉽게 읽을 수 있습니다!
(하나는 없지만 회색 수염을 가진 유닉스 베테랑이되면 많은 도움이 될 것입니다.)


17
... && ... || ...그 의미 상 동등한 아니다으로 보통 (이 시간 죄송 수염이 희끗 희끗 한 유닉스 베테랑, 당신은 봤는데 잘못)에 싫은 내색을한다 if ... then ... else .... 걱정하지 마십시오 . 이것은 일반적인 함정 입니다.
gniourf_gniourf

6
@gniourf_gniourf OP는 잘못된 것이 아니며 제안한대로 무지 할 수도 있습니다. ... && ... || ...완벽하게 유효한 패턴이며 일반적인 bash 관용구입니다. 그것의 사용은 사전 지식을 규정하지만 (관중에 초보자가있는 경우 명심해야 할 수도 있음) OP는 맨홀 뚜껑을 열지 않는 방법을 알고 있음을 입증합니다.
ebpa

3
@ebpa && 뒤에 오는 명령문이 false 값을 리턴하면 실행은 || ? 그렇다면 그것은 틀 렸으며 아마도 gniourf가 제안한 것입니다
TSG

4
나는 반향이 단지 예라고 생각했다. && 다음에 나오는 문장은 여전히 ​​0이 아닌 값을 반환 할 수 있습니다
TSG

2
Bash Pitfalls에 대한 링크를 게시 해 주신 @gniourf_gniourf +1! 매우 유용한!
재규어

21

유스 케이스 / esac을 사용할 수도 있습니다

case "$string" in
 "$pattern" ) echo "found";;
esac

이 동등성 또는 포함입니까?
ytpillai

@ytpillai는 동등성입니다. 으로 |시작하기 전에 패턴을로 구분할 수 있습니다 ). in문에 해당 thenif문. 파이썬에서 온 경우 각 목록에 수행 할 작업에 대한 자체 선언이있는 패턴 목록에 대해 작동한다고 주장 할 수 있습니다. 좋아하지 substring in string않고 오히려 for item in list. 조건 *을 원하면 마지막 진술로를 사용하십시오 else. 처음 만나면 돌아옵니다.
mazunki

18

다음 스크립트는 "testonthis"라는 파일을 한 줄씩 읽은 다음 각 줄을 간단한 문자열, 특수 문자가있는 문자열 및 정규식과 비교합니다. 일치하지 않으면 스크립트가 줄을 인쇄하고 그렇지 않으면 줄을 인쇄합니다.

Bash의 공간은 매우 중요합니다. 따라서 다음이 작동합니다.

[ "$LINE" != "table_name" ] 

그러나 다음은 그렇지 않습니다.

["$LINE" != "table_name"] 

따라서 그대로 사용하십시오.

cat testonthis | while read LINE
do
if [ "$LINE" != "table_name" ] && [ "$LINE" != "--------------------------------" ] && [[ "$LINE" =~ [^[:space:]] ]] && [[ "$LINE" != SQL* ]]; then
echo $LINE
fi
done

이 방법 을 사용 하여 파일을 살펴보십시오. 즉, 무엇보다도 UUoC를 제거하십시오.
fedorqui 'SO 중지 피해'

그것은 중요하지 bash않지만 [실제로는 외부 바이너리 이기 때문에 (과 which [같은 수율로 /usr/bin/[)
Patrick Bergner

11

입력에 유효한 항목이 몇 개인 경우 정규 표현식 일치를 사용합니다. 예를 들어 "시작"및 "중지"만 유효한 작업입니다.

if [[ "${ACTION,,}" =~ ^(start|stop)$ ]]; then
  echo "valid action"
fi

$ACTION이중 쉼표를 사용하여 변수 를 소문자 로 사용합니다. 또한 이것은 너무 오래된 bash 버전에서는 작동하지 않습니다.


9

배쉬 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

즐겨.


나를 위해 (맥 GNU bash 버전 4.4.12 (1)-릴리스 x86_64-apple-darwin17.0.0), 내가 사용해야 if [ "$a"="$b" ]하거나 작동하지 않습니다 ... 등호 주위에 공백을 가질 수 없습니다
스펙트럼

1

Bash 및 Dash (sh) 와 호환되는 방식으로 수행했습니다 .

testOutput="my test"
pattern="my"

case $testOutput in (*"$pattern"*)
    echo "if there is a match"
    exit 1
    ;;
(*)
   ! echo there is no coincidence!
;;esac

선행 (과 사용하지 않는 것의 차이점은 무엇 입니까?
mazunki
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.