Linux grep 및 정규식 문제

Linux grep 및 정규식 문제

아래 코드를 시도하고 0(예: )의 결과를 얻으려고 $? -eq 0하지만 어떤 이유로 항상 실패합니다.

echo "INBOUND_PATH|/tmp" | grep -E '^\(INBOUND_PATH\)\|\(.*\)$';

echo $?

역참조를 생성하려는 이유는 문자열 형식이 유효하면 다음을 사용하여 디렉터리를 잘라내기 때문입니다.

g_inboundDir=grep -E 's/^\(INBOUND_PATH\)\|(.*)$/\2';

답변1

공백과 모든 답변을 종합하고 man grepgrep()의 매뉴얼 페이지를 보면 두 가지 주요 정규식 유형, 즉 기본 정규식과 확장 정규식이 있습니다.

man grep에 따르면:

기본 정규식과 확장 정규식
기본 정규식에서 메타 문자 ?, +, {, |, ( 및 )는 백슬래시 버전 \?, +, {, \|, ( 및 ) 대신 특별한 의미를 잃습니다.

즉, 이스케이프된 괄호를 사용하거나 필요하지 않은 경우 이스케이프된 ()유사 또는 단일 grep 캡처 그룹을 사용할 수 있습니다.grep \(....\)grep -Eegrepegrep '(....)'

sed에도 동일한 규칙이 적용됩니다. 간단한 sed는 기본 정규식을 이해하므로 그룹을 캡처하려면 이스케이프가 필요합니다. 또는 sed 's/\(....\)\(...\)/\2/'sed 구현에 따라 with 또는 switch에서 확장 정규식 지원을 활성화할 수 있습니다.sed-E-rsed -E 's/(...)(...)/\2/'

따라서 다음 명령은 모두 유효합니다.

$ echo "INBOUND_PATH|/tmp" | grep '^\(INBOUND_PATH\)|\(.*\)$';echo $?
INBOUND_PATH|/tmp
0

$ echo "INBOUND_PATH|/tmp" | egrep '(INBOUND_PATH)\|(.*)$';echo $?
INBOUND_PATH|/tmp
0

$ echo "INBOUND_PATH|/tmp" | sed 's/^\(INBOUND_PATH\)|\(.*$\)/\2/'
/tmp

$ echo "INBOUND_PATH|/tmp" | sed -E 's/(INBOUND_PATH)\|(.*)$/\2/'
/tmp

다양한 정규식에서 특수 기호를 반대로 처리하는 방법에 유의하세요.

|예를 들어 위 명령에서 파이프 기호 처리를 참조하세요.
BRE(기본 정규 표현식):
리터럴 파이프 기호와 일치시키기 위해 파이프 기호를 이스케이프할 필요가 없습니다.
BRE에서 이스케이프된 파이프 기호는 OR 연산자로 처리됩니다(귀하의 경우에는 예기치 않게 작동함).

마찬가지로 BRE에서는 리터럴 대괄호와 일치시키기 위해 이스케이프 대괄호를 사용할 필요가 없지만 ( )그룹을 캡처하려면 이스케이프 대괄호가 필요합니다.

확장 정규식(ERE):
문자 그대로 일치하려면 파이프 기호를 이스케이프해야 합니다. 기본적으로 ERE에서는 파이프 기호가 OR 연산자로 처리되기 때문입니다(BRE와 비교하여 처리가 반대임).

(마찬가지로 ERE에서는 기본적으로 ERE의 대괄호가 그룹 캡처에 사용되므로 리터럴 대괄호와 일치하도록 대괄호를 이스케이프해야 합니다 .

답변2

문자열의 기본 검사는 그렇게 복잡할 필요가 없습니다.
echo "INBOUND_PATH|/tmp" | grep -q '^INBOUND_PATH|.*$'

나는 두 번째 것이 grep이 아니라 sed라는 것을 의미한다고 가정합니다.
g_inboundDir=$(echo "INBOUND_PATH|/tmp" | sed 's/^\(INBOUND_PATH\)|\(.*$\)/\2/')

-E가 없다는 점에 유의하세요. 누락된 후행 /도 수정했습니다.

답변3

확장 정규식인 -E를 추가하고 싶습니다.

-E, --extended-regexp PATTERN을 확장 정규식(ERE, 아래 참조)으로 해석합니다.

그리고 여전히 그것으로부터 도망치고 있습니다. 불필요한.

$ echo "INBOUND_PATH|/tmp" | grep -E '^(INBOUND_PATH)\|(\/.*)'; echo $?
INBOUND_PATH|/tmp
0

반면에 다음을 사용할 수 있습니다.에그레프-E 없이 동일한 효과를 갖습니다.

관련 정보