이 질문에 대한 답변을 찾을 수 없습니다. 중복된 질문이라면 사과드립니다.
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이 끝에 있습니다.