POSIX sed에서 마침표(점)가 여러 줄 패턴 공간의 개행 문자와 일치합니까?

POSIX sed에서 마침표(점)가 여러 줄 패턴 공간의 개행 문자와 일치합니까?

GNU sed에서는 작동합니다. 예를 들어, 이는 여러 줄 패턴 공간에서 두 개의 빈 줄과 일치합니다(다음을 N사용하여 생성됨).

/^\n$/

이게 표준인가요?

답변1

예.

기본/확장 정규식

.대괄호 표현식 외부에서 사용되는 마침표 는 [n] [BE]RE이며, 이는 NUL을 제외하고 지원되는 문자 집합의 모든 문자와 일치합니다.[]

많은 POSIX 정규식 구현(예를 들어 grep또는 sed)개행 문자가 일치하지 않기 때문에 일치시키는 것이 어렵지 않지만 .입력 구분 기호가 개행 문자이므로 스캔된 문자열에서 일치시킬 개행 문자가 없습니다.

POSIX는 grep개행 문자와 일치할 수 없습니다. 이는 빈 문자열과 동의어입니다 grep. sed유사하지만 a는 sed편집을 수행하거나 스크립트 명령을 기반으로 추가 입력을 가져올 수 있으며 이러한 결과에는 패턴 공간에서 발생하지 않더라도 개행 문자가 포함될 수 있습니다. 하지만 이 경우에는 .ewline이 일치됩니다 \n.

내가 아는 한, POSIX 구현이 거의 할 수 없는 일이 하나 있는데, 그것은 ^개행 문자의 보완과 일치합니다. 이는 \백슬래시가 [대괄호 표현식에서 자신을 나타내기 때문입니다 ]. 따라서 \n이스케이프는 단순히 \and를 의미합니다 n. 정규식에 리터럴 개행 문자를 포함하는 것도 일반적으로 구문 오류이기 때문입니다.( pax이것은 내가 알고 있는 유일한 예외이지만), 넌 이러면 안 돼[^<newline>]가지고 다닐 수 있는.

정상적인 구현에서는 이를 처리해야 "[$(printf '\1-\11\13-\377')]"하지만 이로 인해 멀티바이트 시나리오에서 일치가 제한됩니다.

또한: "\(\([^[:space:]]*[[:blank:]$(printf '\r\v\f')]*\)*\)"하지만 이건 좀 투박해요.

하지만 당신이 할 수 있는 일은 패턴 공간의 모든 개행 문자를 일시적으로 다른 문자로 바꾸는 것입니다.(물론 그 반대도 마찬가지), 그런 다음 해당 다른 문자의 보수와 일치합니다.

예를 들어:

printf %s\\n "a a" "b b" "c c" |
sed -e 'H;1h;$!d;x;l' -e '# slurps input to last line - usually a bad idea'   \
    -e 'y/ \n/\n /;l' -e '# transliterates spaces and newlines at once'       \
    -e 's/[^ ]*//2;l' -e '# substitutes away 2cd sequence of not spaces'      \
    -e 'y/ \n/\n /;l' -e '# transliterates spaces and newlines again'

a a\nb b\nc c$
a\na b\nb c\nc$
a\na  c\nc$
a a\n\nc c$
a a

c c

그 작은 스크립트에는 4개의 ook 명령이 있습니다 l. 하나는 마지막 줄을 찾은 후 매번 패턴 공간을 변경하는 것입니다. 각 look 명령은 위의 처음 4개 출력 줄 중 하나에 해당하며 $후행 문자로 쉽게 표시됩니다.

마지막 세 줄은 sed기본적으로 stdout에 인쇄된 모든 편집 내용의 결과입니다. 공백 문자의 보수의 두 번째 시퀀스가 ​​대체되기 때문에 두 번째 줄은 완전히 비어 있습니다. sed이는 입력 개행 문자를 제외한 당시 패턴 공간의 모든 문자와 일치하므로 두 번째 시퀀스는 전체 두 번째 줄에서 해당 항목을 뺀 값입니다. 후행 개행 구분 기호.

중요한 것은 이것이 작동한다는 것입니다.왜냐하면가리키다(또는 더 제한적인 [대괄호 표현 ]대안)개행 문자와 일치합니다.

관련 정보