첫 번째 경기 만 잡고


328

grep을 사용하여 첫 번째 일치 항목 만 반환하기를 희망하면서 다음 인수와 함께 디렉토리를 재귀 적으로 검색하고 있습니다. 불행히도, 마지막으로 보았을 때 실제로 두 개 이상을 반환합니다. 특히 원하는 결과를 얻지 못한 채 논쟁이 너무 많은 것 같습니다. :-/

# grep -o -a -m 1 -h -r "Pulsanti Operietur" /path/to/directory

보고:

Pulsanti Operietur
Pulsanti Operietur

아마도 grep이 최선의 방법이 아닐까요? 정말 고마워요

답변:


510

-m 1주어진 파일에서 첫 번째 일치 항목을 반환합니다. 그러나 여전히 다른 파일에서 계속 검색합니다. 또한 같은 줄에 두 개 이상의 일치 항목이 있으면 모두 표시됩니다.

head -1이 문제를 해결하는 데 사용할 수 있습니다 .

grep -o -a -m 1 -h -r "Pulsanti Operietur" /path/to/dir | head -1

각 grep 옵션에 대한 설명 :

-o, --only-matching, print only the matched part of the line (instead of the entire line)
-a, --text, process a binary file as if it were text
-m 1, --max-count, stop reading a file after 1 matching line
-h, --no-filename, suppress the prefixing of file names on output
-r, --recursive, read all files under a directory recursively

대박! 감사합니다. btw-내가 명령에 가지고있는 다른 모든 주장이 필요합니까? 우연히 파이프를 만들 수 없다면 어떻게됩니까?
Tim Kamm

2
나는 그들이 필요하다고 생각하지 않지만 ( -r분명히 제외하고 ) 아프지 않아야합니다 ( -a그렇지만 사용 하지는 않겠습니다 )
mvp

3
정확히 내가 필요한 것. 내 패턴은 같은 줄에서 두 번 발견되었으며이 grep -m 1때문에 두 인스턴스를 모두 반환했습니다. |head -1해결했다!
harperville

6
@Chris_Rands 정확한 동작은 실행중인 쉘에 따라 다릅니다. head는 첫 번째 줄에 도달하자마자 종료됩니다. grep은 다음에 헤드가 종료 된 후 쓰기를 시도 할 때 종료됩니다. 일부 쉘은 파이프 라인의 모든 요소가 완료 될 때까지 대기하며 일부는 파이프의 마지막 프로그램이 종료되는 즉시 전체 파이프를 종료시킵니다.
puhlen

1
@ 3Qn, 귀하의 의견을 이해하지 못합니다 : first not first from result. 이 답변은 모든 파일에서 첫 번째 일치 항목을 인쇄하고 중지합니다. 그 밖의 무엇을 기대 했습니까?
mvp

31

stdbuf 와 함께 grep결과를 파이프 할 수 있습니다 .head

N 번째 일치 후 중지를 보장하려면 출력을 버퍼링하지 않도록 stdbuf사용해야 grep합니다.

stdbuf -oL grep -rl 'pattern' * | head -n1
stdbuf -oL grep -o -a -m 1 -h -r "Pulsanti Operietur" /path/to/dir | head -n1
stdbuf -oL grep -nH -m 1 -R "django.conf.urls.defaults" * | head -n1

head줄 을 소비 하자마자 종료 되어 파이프에 무언가를 출력했기 때문에 grep수신됩니다 .SIGPIPEhead

이것은 파일 이름에 개행 문자가 포함되어 있지 않다고 가정했습니다.


내가 가진 아카이브 많은 수의 파일에서 검색하는이 솔루션을 채택하기 위해 노력하고있어 xargs: find . -name '*.gz' | xargs -I '{}' stdbuf -oL zgrep -al 'pattern' {} | head -n 1. 그러나 이것은 첫 번째 경기에서 종료되지 않습니다. 어떤 충고?
DKroot

1
하지 않을까요 grep--line-buffered옵션은 추가적인 유틸리티를 호출하지 않고 오버 헤드 버퍼 방지?
David

23

내 grep-a-like 프로그램 ack에는 -1어디서나 발견 된 첫 번째 경기에서 멈출 수 있는 옵션이 있습니다. -m 1@mvp도 참조 하는 것을 지원합니다 . 하나의 파일에만 존재하는 것을 찾기 위해 큰 소스 코드 트리를 검색하는 경우 파일을 찾을 필요가 없으므로 Ctrl-C를 눌러야하기 때문에 여기에 넣었습니다.


ack가 grep보다 빠르다고 말할까요? 나는 또한 속도 요소에 정말로 관심이 있습니다.
Tim Kamm

1
ack는 검색 대상에 따라 grep보다 빠를 수 있습니다. ack는 소스 코드 검색에 관한 것입니다. 일반 파일을 검색하려는 경우 적어도 ack 1.x에서는 그 정도가 좋지 않습니다. ack에 대해 읽고 그것이 귀하의 요구에 맞는지 확인하십시오.
Andy Lester

2
나는 오랫동안 Ack를 사용해 왔지만 최근 에 Ack를 더 빨리 찾은 은색 검색기
바꿨다

OP가 grep으로 원한다고 말했기 때문에 이것이 유일한 대답이어야한다고 생각하지만 다른 대답은 head (물론 두 작업 모두)를 사용하지만 grep이 일반적이고 tail / 머리가 아닙니다.
Areeb Soo Yasir

가치는 그 언급 ag빨리 될 수도 있지만 그것은 하지 않습니다-1이 경우에 유용합니다 옵션
JJA

3

검색중인 현재 디렉토리에서 특정 단어가 나타나면 전체 줄과 파일 이름을 인쇄하려면 아래 명령을 사용할 수 있습니다.

grep -m 1 -r "Not caching" * | head -1

2

다음을 사용하는 단일 라이너 find:

find -type f -exec grep -lm1 "PATTERN" {} \; -a -quit

6
find는 발견 된 모든 파일에 대해 grep 사본을 생성 하므로 매우 느려질 것입니다. grep -r디렉토리 탐색을 수행하는 유일한 사본-훨씬 빠르게 작동합니다.
mvp

진실; 그러나 find는 필터링 된 결과에서만 작동하도록 사용자 정의 할 수 있으며, 따라서 포괄적 인 grep보다 훨씬 빠르게 작업을 수행 할 수 있습니다. 상황에 따라 다릅니다.
얌 마르코비치
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.