‘grep -q’가 전체 입력 파일을 사용하는 이유는 무엇입니까? sed -n 2q; cat;

다음 입력 파일을 고려하십시오.

1
2
3
4

달리는

{ grep -q 2; cat; } < infile

아무것도 인쇄하지 않습니다. 나는 그것을 인쇄 할 것으로 예상된다

3
4

변경하면 예상 출력을 얻을 수 있습니다.

{ sed -n 2q; cat; } < infile

첫 번째 명령이 예상 출력을 인쇄하지 않는 이유는 무엇입니까?
검색 가능한 입력 파일이며 OPTIONS표준에 따라 다릅니다 .

-q
      Quiet. Nothing shall be written to the standard output, regardless of
      matching lines. Exit with zero status if an input line is selected.

그리고 APPLICATION USAGE ( 강하게 강조) 에서 아래로 :

-q옵션을 사용하면 파일 그룹에 패턴 (또는 문자열)이 있는지 여부를 쉽게 확인할 수 있습니다. 여러 파일을 검색 할 때 성능이 향상됩니다 ( 첫 번째 일치 항목을 찾 자마자 종료 될 수 있기 때문에 ) […]

이제 동일한 표준에 따라 ( 소개 , 입력 파일 아래에 있음 )

표준 유틸리티가 탐색 가능한 입력 파일을 읽고 파일 끝에 도달하기 전에 오류없이 종료되는 경우 , 유틸리티는 열린 파일 설명의 파일 오프셋이 유틸리티가 처리 한 마지막 바이트 바로 뒤에 올바르게 위치하도록해야합니다 [. ..]

tail -n +2 file
(sed -n 1q; cat) < file
...

두 번째 명령은 파일을 찾을 수있는 경우에만 첫 번째 명령과 같습니다.


grep -q전체 파일을 소비합니까?


이것은 gnu grep중요하다면 ( Kusalananda 가 OpenBSD에서 동일한 일이 발생했음을 확인 했지만 )



답변

grep 일찍 멈추지 만 입력을 버퍼링하므로 테스트가 너무 짧습니다 (그리고 테스트를 찾을 수 없기 때문에 테스트가 불완전하다는 것을 알았습니다).

seq 1 10000 | (grep -q 2; cat)

내 시스템에서 6776에 시작합니다. GNU grep에서 기본적으로 사용되는 32KiB 버퍼 와 일치 합니다 .

seq 1 6775 | wc

출력

   6775    6775   32768

POSIX는 성능 향상만을 언급합니다.

여러 파일을 검색 할 때

단일 파일을 부분적으로 읽음으로써 성능 향상에 대한 기대치를 설정하지는 않습니다.


답변

이것은 분명히 grep속도를 높이는 버퍼링 때문입니다. 요청한 문자 수만큼만 읽도록 특별히 설계된 도구가 있습니다. 그들 중 하나는 expect:

{ expect -c "log_user 0; expect 2"; cat; } < infile

나는 이것을 시도 할 시스템이 없지만 expect예상되는 문자열 ( 2)을 만날 때까지 모든 것을 먹은 다음 종료하고 나머지 입력은 그대로 둡니다 cat.


답변

sed와 grep을 혼동하고 있습니다.

sed 명령의 -2q경우 두 번째 줄에서 -n옵션이 조용히 작동한다고 말하면 현재 반복을 종료한다고 말하고 두 번째 줄 이후에 모든 줄을 얻습니다.

grep 명령은 기본적으로 모든 일치하는 행을 출력하기 위해 실행되지만 -q옵션은 stdout에 아무것도 출력하지 않습니다. 따라서 입력에 “2”가 포함되어 있으면 종료 값이 SUCCESS이고 그렇지 않으면 FAILURE입니다. 그것들은 운영 체제와 쉘에 따라 다릅니다. 따라서 일반적으로 grep 프로세스의 종료 값을 검사하여 행이 일치하는지 알 수 있습니다. 이것은 입력에 테스트 값이 포함되어 있는지 알고 싶은 파이프 라인에서 유용합니다. 예 :

if grep -q 'crash' <somelog.log ; then report_crash_via_email ; fi

이 경우 일치하는 줄을 모두 보지 않아도되며, 적어도 한 줄만 있으면됩니다. report_crash_via_email프로세스 / 기능은 전원을 껐다 갈 수 있으며 파일을 다시는-열거 나하지.

“2”문자를 찾은 후 grep 프로세스를 중지하려면 기본적으로는 아니고 모든 행을 검사하여 일치하는지 확인합니다.이를 수행하도록 지시해야합니다. 해당 명령 줄 스위치는 -m <value>입니다. 귀하의 경우에는 grep -q -m1 2.