대소 문자를 구분하지 않는 명령 문자열을 명령 출력과 일치시키는 쉘 스크립트를 작성하려면 어떻게해야합니까?
bash
은 유닉스 표준sh
의 상위 집합입니다 . 다음 중 하나를보고 시작할 수 있습니다. | 1 | | 2 | -실제 상황이 무엇인지 파악하기 위해.
대소 문자를 구분하지 않는 명령 문자열을 명령 출력과 일치시키는 쉘 스크립트를 작성하려면 어떻게해야합니까?
bash
은 유닉스 표준sh
의 상위 집합입니다 . 다음 중 하나를보고 시작할 수 있습니다. | 1 | | 2 | -실제 상황이 무엇인지 파악하기 위해.
답변:
먼저 대소 문자를 무시하지 않는 간단한 예제 스크립트가 있습니다.
#!/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 ]
==
POSIX가 아닙니다. 모든 Linux 기반 시스템에있는 sh
것은 아닙니다 bash
. ==
는 ash
( sh
많은 BSD 및 데비안 파생물 중 적어도 기반이되는) 또는에서 지원되지 않으며로 posh
인용해야합니다 zsh
. 을 두 배로 늘릴 점이 없습니다 =
. [
테스트 명령입니다. 할당과 비교를 명확하게 할 필요는 없습니다. 즉 다른입니다 (( a == b ))
대 (( a = b))
. 로 ==
시작하는 스크립트에서 사용 하는 #! /bin/sh
것이 잘못되었습니다. 가정 ksh
하거나 bash
구문을 사용하면 #!
그에 따라 업데이트하십시오 .
쉘 옵션 을 설정하면 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
[[ XYZ == xyz ]] && echo "match"
=>match
변수 값의 대소 문자 문자열 검색을위한 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
있습니다 tr
GNU의로 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
당신은 절대로 그렇게하지 않는 한.
<<<
ksh, bash, zsh 연산자 를 가진 쉘에서만 작동 하지만 일반 sh는 작동하지 않습니다. 그리고 printf
실행 방식 측면 에서 파이핑에 매우 가깝습니다 . fork
및 호출 횟수는 동일합니다 execve
( printf
내장 된 경우, 가장 일반적인 쉘의 경우). 차이점은 <<<
파이프를 사용하지 않고 임시 파일 을 작성한다는 것입니다. <<<
입력하기 편리하지만 성능 향상이 아닙니다.
grep -i
아마도?