쉘 스크립트에서 대소 문자를 구분하지 않는 부분 문자열 검색 [닫기]


22

대소 문자를 구분하지 않는 명령 문자열을 명령 출력과 일치시키는 쉘 스크립트를 작성하려면 어떻게해야합니까?


grep -i아마도?
Ramesh

스크립트 안에 어떻게 넣을까요? 이것이 초보자 질문이라면 죄송합니다. 인턴쉽에 Linux가 필요하기 때문에 Linux를 배우기 시작했습니다. 감사!
Miguel Roque

1
당신이 요구하는 것은 쉘 스크립팅입니다 . "linux"는 프로그래밍 언어가 아니며, 운영 체제 커널입니다. 리눅스에서 가장 일반적으로 사용되는 쉘 bash유닉스 표준sh 의 상위 집합입니다 . 다음 중 하나를보고 시작할 수 있습니다. | 1 | | 2 | -실제 상황이 무엇인지 파악하기 위해.
goldilocks

1
이 질문은 이제 분명해 보이며 도움말 센터의 지침과 일치합니다. 다른 사람의 이익을 위해 열 수 있습니까?
BobDoolittle 2016 년

2
이 질문이 왜 명확하지 않은지 잘 모르겠습니다. 명확하게하기 위해 무엇을 추가해야합니까?
Miguel Roque

답변:


11

먼저 대소 문자를 무시하지 않는 간단한 예제 스크립트가 있습니다.

#!/bin/bash
if [ $(echo hello) == hello ]; then
    echo it works
fi

오른쪽의 문자열 hello를 변경하면 더 이상 에코되지 않습니다 it works. echo hello선택한 명령으로 바꾸 십시오. 대소 문자를 무시하고 문자열에 줄 바꿈이 포함되어 있지 않으면 grep을 사용할 수 있습니다.

#!/bin/bash
if echo Hello | grep -iqF hello; then
    echo it works
fi

여기서 핵심은 명령 출력을에 파이프한다는 것 grep입니다. if이 경우 그렙에 - 문은 파이프 라인의 오른쪽 명령의 종료 상태를 테스트합니다. Grep이 일치하는 경우에만 성공으로 종료됩니다.

-i의 grep 옵션은 사건을 무시했다.
-q옵션은 첫 번째 일치 후에 출력을 내 보내지 않고 종료한다고 말합니다.
-F옵션은 인수를 정규식이 아닌 문자열로 취급한다고 말합니다.

첫 번째 예는 직접 비교 및 ​​다양한 유용한 연산자를 허용하는 사용합니다. 두 번째 양식은 명령을 실행하고 종료 상태를 테스트합니다.[ expression ]


Gilles가 내가 기여한 코드를 변경해야한다고 생각한 이유를 이해하지 못합니다. 그는 아무것도 깨지 않았지만 잘 작동했습니다. 이 예제에서는 큰 따옴표가 필요하지 않습니다. 그러나 출력에 공백이 있으면 중요합니다. sh는 Linux에서 실제로 bash이기 때문에 ==와 마찬가지로 작동합니다. 원래 Bourne Shell은이 시점에서 오랫동안 사라졌습니다. 솔라리스조차도 더 이상 출하하지 않는다고 생각합니다. 이 예제에서는 불필요하지만 큰 따옴표는 아마도 가장 좋은 방법 일 것입니다.하지만 할당과 비교를 명확하게 구분하기 위해 내 의견으로는 '=='입니다.
BobDoolittle

잠깐만 요, 글을 편집 할 수 있습니까? 난 몰랐어.
Miguel Roque

충분한 평판을 가지고 있습니다. 그러나 평판이 좋은 사람은 특히이 포럼의 코드를 편집하기 위해 불필요한 편집을하기 전에 두 번 생각하기를 바랍니다. unix.stackexchange.com/help/privileges
BobDoolittle

@BobDoolittle 경우에 따라 차이가있을 수 있지만 설정과 다를 수 있습니다 . 알아두면 좋습니다.

2
실제로는 Bourne 쉘에만 국한되지 않습니다. ==POSIX가 아닙니다. 모든 Linux 기반 시스템에있는 sh것은 아닙니다 bash. ==ash( sh많은 BSD 및 데비안 파생물 중 적어도 기반이되는) 또는에서 지원되지 않으며로 posh인용해야합니다 zsh. 을 두 배로 늘릴 점이 없습니다 =. [테스트 명령입니다. 할당과 비교를 명확하게 할 필요는 없습니다. 즉 다른입니다 (( a == b ))(( a = b)). 로 ==시작하는 스크립트에서 사용 하는 #! /bin/sh것이 잘못되었습니다. 가정 ksh하거나 bash구문을 사용하면 #!그에 따라 업데이트하십시오 .
Stéphane Chazelas

49

쉘 옵션 을 설정하면 bash정규식 연산자 를 사용하여 대소 문자를 구분하지 않는 부분 문자열 일치를 기본적으로 수행 할 수 있습니다 . 예를 들어=~nocasematch

s1="hElLo WoRlD"
s2="LO"

shopt -s nocasematch

[[ $s1 =~ $s2 ]] && echo "match" || echo "no match"
match

s1="gOoDbYe WoRlD"
[[ $s1 =~ $s2 ]] && echo "match" || echo "no match"
no match

6
롤! 모호한 쉘 지식에 대한 포인트.
BobDoolittle

2
이 옵션은 단순 일치 연산자에도 영향을줍니다. [[ XYZ == xyz ]] && echo "match"=>match
itsadok

7

변수 값의 대소 문자 문자열 검색을위한 needle변수의 값 haystack:

case "$haystack" in
  *"$needle"*) echo "present";
  *) echo "absent";
esac

대소 문자를 구분하지 않는 문자열 검색의 경우 둘 다 동일한 대소 문자를 변환하십시오.

uc_needle=$(printf %s "$needle" | tr '[:lower:]' '[:upper:]' ; echo .); uc_needle=${uc_needle%.}
uc_haystack=$(printf %s "$haystack" | tr '[:lower:]' '[:upper:]' ; echo .); uc_haystack=${uc_haystack%.}
case "$uc_haystack" in
  *"$uc_needle"*) echo "present";;
  *) echo "absent";;
esac

있습니다 trGNU의로 coreutils에서 멀티 바이트 로케일을 지원하지 않습니다 (예 : UTF-8). 멀티 바이트 로케일로 작업하려면 awk를 대신 사용하십시오. awk를 사용하려는 경우 변환뿐만 아니라 문자열 비교를 수행 할 수 있습니다.

if awk 'BEGIN {exit !index(toupper(ARGV[2]), toupper(ARGV[1]))}' "$needle" "$haystack"; then
  echo "present"
else
  echo "absent"
fi

tr비지 박스에서는 지원하지 않습니다 구문을; 대신 사용할 수 있습니다 . BusyBox는 비 ASCII 로케일을 지원하지 않습니다.[:CLASS:]tr a-z A-Z

버전 4.0+ 인 bash (sh는 아님)에는 대 / 소문자 변환을위한 내장 구문과 문자열 일치를위한 간단한 구문이 있습니다.

if [[ "${haystack^^}" = *"${needle^^}"* ]]; then
  echo "present"
else
  echo "absent"
esac

나는 이것이 두 살이라는 것을 알고 있지만, printf | tr내 머리가 돌게합니다. 가능하면 명령 v을 최소한으로 유지하십시오. 변수 v가 ​​주어지면을 사용하여 동일한 것을 수행 할 수 있습니다 v=$(tr '[:lower:]' '[:upper:]' <<<$v). 이전에 본 적이없는 사람들에게이 문서 <<<는 본질적으로 "여기 변수" <<EOF입니다. 하지 마십시오 printf또는 echo당신은 절대로 그렇게하지 않는 한.

@Will 그것은 <<<ksh, bash, zsh 연산자 를 가진 쉘에서만 작동 하지만 일반 sh는 작동하지 않습니다. 그리고 printf실행 방식 측면 에서 파이핑에 매우 가깝습니다 . fork및 호출 횟수는 동일합니다 execve( printf내장 된 경우, 가장 일반적인 쉘의 경우). 차이점은 <<<파이프를 사용하지 않고 임시 파일 을 작성한다는 것입니다. <<<입력하기 편리하지만 성능 향상이 아닙니다.
Gilles 'SO- 악마 그만해'
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.