세 개의 연속된 개행 문자를 검색하시겠습니까?

세 개의 연속된 개행 문자를 검색하시겠습니까?

여러 빈 줄을 squeeze 사용할 수 있다는 것을 알고 있습니다. cat -s(그리고 squeeze all 빈 줄을 사용할 수도 있습니다 tr -s '\n'.) 하지만 어떻게 하는지 궁금합니다.찾다이 경우 입력 스트림에서.

stream-of-input | grep -qz $'\n\n\n'그러면 괜찮을 거라 생각했는데 그렇지 않더라고요.

간단한 도구로 이런 종류의 검색을 수행할 수 있는 방법이 있습니까?

즉, 세 개의 연속된 바이트가 개행인 경우 입력을 읽고 0 상태로 종료합니다. 세 개의 연속된 개행이 발견되지 않고 EOF에 도달하면 0이 아닌 상태로 종료됩니다.

답변1

tr다음을 사용하여 스트림을 일반적으로 grep할 수 있는 스트림으로 변환 할 수 있습니다 .

stream | tr 'x\n' '\0x' | grep -qz xxx

이는 모든 x바이트를 널 바이트로 변환하고 모든 개행 바이트를 xs로 변환합니다. 이는 평소와 같이 grep 출력할 수 있습니다. 즉, linefeed -> x -> null 경로를 따라 한 단계 이동하므로 3개의 개행 문자 시퀀스는 이제 x3개의 s 시퀀스가 ​​되며 x다른 바이트는 나타나지 않습니다(null 종료 행이 됩니다 grep).


이게 효과가 있어POSIX와 함께tr이지만 grep -z확장입니다. 너가능한필요하지 않습니다. 여기서는 분리된 동작이 필요하지 않으며 대부분 grep의 은 이진 데이터를 처리하지만POSIX는 grep텍스트 파일만 처리하면 됩니다.따라서 어떤 방식으로든 확장 기능에 의존하게 될 것입니다.

실제 데이터가 텍스트 파일이거나 바이너리 안전 동작에 의존하지 않는다면 아마도 살아남을 수 있을 것입니다.

stream | tr 'x\n' '\nx' | grep -q xxx

- 즉, 2바이트만 교환하면 됩니다. 이것은거의POSIX와 호환되지만 실제로는 거의 모든 곳에서 작동할 것입니다(문제는 마지막 줄입니다).제대로 종료되지 않으므로 텍스트 파일이 아니므로 grep엄격하게 수락을 요구하지는 않습니다.).

두 경우 모두 가능한 문제 중 하나는 기존 바이트가 없는 파일이 하나의 매우 긴 줄로 처리되어 x구현에서 처리할 수 있는 제한을 초과할 수 있다는 것입니다. grep예상되는 다른 공통 바이트를 선택하면 문제가 해결될 수 있습니다.

원래 명령이 작동하지 않는다는 사실에 놀랐지 grep -qz $'\n\n\n'만 오류가 있습니다.긍정적인나에게 문제는 다음과 같이 작동 grep -qz ''하고 항상 일치하는 것 같습니다. 왜 이렇게 되어야 하는지 모르겠습니다.

답변2

lex( 또는 )는 이를 처리할 수 있습니다. 예를 들어 다음은 주로 표준 출력으로의 기본 출력을 방지하기 위해 추가 규칙을 사용하여 flex파일에 저장합니다.tresn.l

%%
\n\n\n  { exit(0); }
<<EOF>> { exit(1); }
\n\n    { ; }
\n      { ; }
.       { ; }
%%

암시적 규칙을 사용하여 컴파일되고 make도입됨libfl*

$ CFLAGS=-lfl make tresn
lex  -o lex.tresn.c tresn.l
cc -lfl   -o tresn lex.tresn.c  -ll
rm -f lex.tresn.c
$ printf "\n\n" | ./tresn ; echo $?
1
$ printf "\n\n\n" | ./tresn ; echo $?
0

일부 시스템에서는 공급업체 컴파일 공간 외부의 시스템 아래에 특정 포트나 패키지를 추가 -L/opt/local/lib하거나 CFLAGS숨겨야 할 수도 있습니다 .LDFLAGSlibfl*

관련 정보