"grep -q"가 전체 입력 파일을 소비하는 이유는 무엇입니까?

"grep -q"가 전체 입력 파일을 소비하는 이유는 무엇입니까?

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

1
2
3
4

달리기

{ grep -q 2; cat; } < infile

아무것도 인쇄되지 않습니다. 인쇄하고 싶어요

3
4

이를 다음과 같이 변경하면 예상한 결과를 얻습니다.

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

첫 번째 명령이 예상한 출력을 인쇄하지 않는 이유는 무엇입니까?
이는 검색 가능한 입력 파일이며 다음을 기반으로 합니다.기준아래에옵션:

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

더 아래로,애플리케이션 사용법(강조):

-q옵션을 사용하면 파일 세트에 패턴(또는 문자열)이 존재하는지 여부를 쉽게 확인할 수 있습니다. 여러 파일을 검색할 때 성능 향상을 제공합니다(첫 번째 일치 항목을 찾으면 종료할 수 있기 때문입니다.)[...]

이제 동일한 기준으로(소개하다, 아래에입력 파일)

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

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

두 번째 명령은 파일을 검색할 수 있는 경우에만 첫 번째 명령과 동일합니다.


grep -q전체 파일을 사용하는 이유는 무엇 입니까?


gnu grep그게 중요 하다면 (그래도선행은 이루기가 어렵다OpenBSD에서도 동일한 일이 발생함을 확인했습니다)

답변1

grep일찍 중지되지만 입력을 버퍼링하므로 테스트가 너무 짧습니다(예, 검색할 수 없기 때문에 테스트가 불완전하다는 것을 알고 있습니다).

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

내 시스템에서는 6776에서 시작합니다. 그 경기32KiB 버퍼GNU grep은 기본적으로 다음을 사용합니다.

seq 1 6775 | wc

산출

   6775    6775   32768

POSIX에서는 성능 개선만 언급합니다.

여러 파일을 검색할 때

단일 파일을 부분적으로 읽으므로 성능 향상을 기대할 수 없습니다.

답변2

grep이는 버퍼링으로 인해 작업 속도가 빨라지기 때문인 것 같습니다 . 일부 도구는 요청한 만큼의 문자를 읽을 수 있도록 특별히 설계되었습니다. 그 중 하나는 다음과 같습니다 expect.

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

이것을 시도해 볼 수 있는 시스템은 없지만 expect예상되는 문자열( )을 만날 때까지 모든 것을 먹어치운 2다음 종료하고 나머지 입력은 남겨둘 것이라고 믿습니다 cat.

답변3

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

sed 명령의 경우 두 번째 줄에 있는 경우 옵션은 자동으로 실행됨을 의미합니다. 즉, -2q현재 반복을 종료한다는 의미이므로 두 번째 줄 이후의 모든 줄을 가져오게 됩니다.-n

grep 명령은 기본적으로 일치하는 모든 행을 인쇄하기 위해 실행됩니다. 그러나 이 -q옵션은 표준 출력에 아무 것도 인쇄하지 않음을 의미합니다. 따라서 입력에 "2"가 포함되어 있으면 종료 값은 "성공"이고 그렇지 않으면 "실패"입니다. 이것이 무엇인지는 운영 체제와 셸에 따라 다릅니다. 따라서 일반적으로 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.

관련 정보