쉘 IF ​​문에서 grep -q와 함께 관계 연산자를 사용하시겠습니까?

쉘 IF ​​문에서 grep -q와 함께 관계 연산자를 사용하시겠습니까?

이 질문에 대한 답변을 찾을 수 없습니다. 중복된 질문이라면 사과드립니다.

BSD /bin/sh에서는 (아니요세게 때리다! ), 다음 IF 문의 구문을 알아내려고 합니다.

두 개의 구성 조항이 있습니다. 별도의 진술로 작성하면 다음과 같습니다.

if [ "$a" == "y" -o "$a" == "Y" ]; then
    if printf '%s' "$b" | grep -qE 'SOME_REGEX'; then
        # both conditions met: do stuff
    fi
fi

if따라서 해결 방법으로 중첩을 사용할 수 있습니다 .

하지만 "if" 문으로 깔끔하게 결합하려면 어떤 구문이 필요합니까?

[ "$a" =~ REGEX" ]참고: 이 셸이 require 대신 직접 정규식 일치 비교(또는 유사)를 허용하는지 아는 것이 유용할 것입니다 grep -q. 하지만 언젠가는 확실히 일치 파일을 갖게 될 것이므로 절을 올바르게 구성하는 방법을 여전히 알고 싶습니다. 내용 및 두 번째 명령문과 유사한 상황 ls -l "$b" | grep -qE 'SOME_REGEX'이므로 인라인 정규식 비교가 작동하지 않습니다... :)

답변1

개인적으로 나는 여기에 중첩된 문을 사용하는 것이 괜찮다고 생각합니다 if. 비록 약간 더 현대적인 구문을 사용하고 싶습니다.

if [ "$a" = "y" ] || [ "$a" = "Y" ]; then
    if printf '%s' "$b" | grep -qE 'SOME_REGEX'; then
        # both conditions met: do stuff
    fi
fi

(이것은 -ism ==입니다 bash)

그것들을 결합하면(IMHO는 가독성이 떨어집니다):

if [ "$a" = "y" ] || [ "$a" = "Y" ] && printf '%s' "$b" | grep -qE 'SOME_REGEX'; then
    # both conditions met: do stuff
fi

~을 위한기초적인사용할 수 있는 정규식 expr(참조다음은 Stéphane Chazelas의 의견입니다.):

if [ "$a" = "y" ] || [ "$a" = "Y" ] && expr "$b" : 'SOME_REGEX' >/dev/null; then
    # both conditions met: do stuff
fi

쉘은 일반적으로 확장된 정규식 일치를 수행할 /bin/sh필요가 없습니다 .[[ ... =~ ... ]]


마지막 참고 사항: 한 줄에 걸쳐 일치하는 정규식텍스트. 파일 이름이 텍스트로 처리되는 경우 개행 문자가 포함된 파일 이름과 같이 한 줄의 텍스트가 아닌 파일 이름은 자동으로 실격 처리됩니다. 파일 이름에 일치하는 정규식을 적용해야 하는 경우 $@배열(in)에 저장된 이름 에 주의하거나 /bin/sh조건자를 지원하는 구현을 사용하세요.find-regex

파일 이름 와일드카드 패턴은 파일 이름을 일치시키는 데 사용됩니다.

답변2

전체 입력이 아닌 각 입력 줄과 일치 하므로 grep일반적으로 임의의 문자열에 맞지 않습니다. 대신 이것을 사용할 수 있습니다 awk(참고:확장 정규식grep -E또는 ) bash의 이해 와 유사합니다 [[ string =~ regexp ]].

regexp_match() {
  awk 'BEGIN{if (ARGV[1] !~ ARGV[2]) exit(1)}' "$@"
}

if [ "$a" = y ] || [ "$a" = Y ] && regexp_match "$b" REGEXP; then
   ...
fi

/ 이항 연산자 는 -a피해야 합니다. -o [POSIX에서는 더 이상 사용되지 않으며 많은 문제가 있습니다. 예를 들어 FreeBSD에서는 다음과 같습니다.

$ a='(' /bin/sh -c '[ "$a" = y -o "$a" = Y ]'
[: closing paren expected

답변3

정규식 $a에 패턴을 연결하고 추가하여 단축할 수 있습니다.$b

 if printf '%s%s\n' "$a" "$b" | grep -qE '^[yY]SOME_REGEX'; then

grep은 줄 일치 도구이므로 \n이 끝에 있습니다.

관련 정보