여러 파일 유형에 대해 grep --include 옵션을 어떻게 사용합니까?


98

일부 디렉토리의 모든 html 파일을 grep하려면 다음을 수행합니다.

grep --include="*.html" pattern -R /some/path

잘 작동합니다. 문제는 일부 디렉토리의 모든 html, htm, php 파일을 grep하는 방법입니다.

grep --exclude /-include 구문을 사용하여 특정 파일을 통해 grep하지 않도록 하면 다음을 수행 할 수있는 것 같습니다.

grep --include="*.{html,php,htm}" pattern -R /some/path

그러나 슬프게도 그것은 나를 위해 작동하지 않을 것입니다.
참고로 내 grep 버전은 2.5.1입니다.

답변:


137

여러 --include플래그 를 사용할 수 있습니다 . 이것은 나를 위해 작동합니다.

grep -r --include=*.html --include=*.php --include=*.htm "pattern" /some/path/

그러나 Deruijter제안 된 대로 수행 할 수 있습니다 . 이것은 나를 위해 작동합니다.

grep -r --include=*.{html,php,htm} "pattern" /some/path/

다음 findxargs같은 용도로 사용할 수 있다는 것을 잊지 마십시오 .

find /some/path/ -name "*.htm*" -or -name "*.php" | xargs grep "pattern"

HTH


1
나는 문제를 본다. --include = " . {html, php}"를 사용하여 쉘이 ' '를 확장하는 것을 방지 하고 동시에 쉘을 중지하여 {html, php}를 확장했습니다. 등호 --include = *는 쉘이 '*'를 확장하는 것을 방지 할 수있는 것 같습니다.
tianyapiaozi

xargs는 실제로 대용품이 아닙니다. 이 기능이 필요한 경우 xargs가 처리하는 것보다 더 많은 파일을 처리하게됩니다.
James Moore

2
@JamesMoore : GNU Parallel을 살펴보십시오 . 대체로 xargs. 이것은 또한 빨리 읽을 가치가 있습니다. HTH.
Steve

3
@tianyapiaozi : 중괄호 확장 주위의 인용문이 문제라는 것이 맞습니다. 인용없이, 그러나, *여전히 글 로빙의 적용을받습니다 가에 포함되는 토큰의 일환으로 , 그냥 일이 파일 만 있기 때문에,이 경우 일치 아무것도하지 말 그대로 같은 이름이 뭔가 --include=foo.html일치하는 것입니다. 안전을 위해 *(를 사용 하여 개별적으로 수행 할 수있는)를 인용하십시오 \*. 추가 보너스로 이것은 이 경우 글 로빙을 수행 해야하는 아닌 것을 시각적으로 더 명확하게 만듭니다 .
mklement0

2
find솔루션에 관해서는 -exec grep "pattern" {} +대신 사용 하는 | xargs grep "pattern"것이 더 강력 할뿐만 아니라 더 효율적입니다 (예 : 공백이있는 파일 이름 처리).
mklement0

32

사용 {html,php,htm}단지로 동작 할 수 있습니다 중괄호 확장 비표준의 (POSIX 호환되지 않음) 기능입니다, bash, ksh,와 zsh.

  • 즉, 대상 스크립트에서 사용하지 마십시오 .이 경우 명시 적 다중 인수를 /bin/sh사용하십시오 .--include

  • grep그 자체는 표기법을 이해 하지 못합니다{...} .

중괄호 확장이 인식 되려면 명령 줄에서 인용되지 않은 (a의 일부) 토큰 이어야합니다 .

중괄호 확장 로 확장 여러 인수를 손에 그래서 경우에, grep보고 끝나는 여러 --include=... 사용자가 개별적으로 통과 한 것처럼, 옵션을.

중괄호 확장의 결과 는 함정이 있는 globbing (파일 이름 확장)의 대상이됩니다 .

  • 각 결과 인수는 다음 과 같이 인용되지 않은 글 로빙 메타 문자 를 포함하는 경우 일치하는 파일 이름으로 확장 될 수 있습니다.* . (예를 들어, 일치하는 것과 같은 이름 의 파일이 있어야 함)
    과 같은 토큰에서는 그렇지 않을 수 있지만 일반적으로 명심할 가치가 있습니다.--include=*.html--include=foo.html

  • 는 IF nullglob쉘 옵션이 켜져하는 일 (shopt -s nullglob )와 일치의 globbing을하지 아무것도 , 인수가됩니다 폐기 .

따라서 완전히 강력한 솔루션 을 얻으려면 다음을 사용하십시오.

grep -R '--include=*.'{html,php,htm} pattern /some/path
  • '--include=*.' 로 취급됩니다 작은 따옴표 로 인해 리터럴 . 이것은 *globbing 문자로의 부주의 한 해석을 방지 합니다.

  • {html,php,htm},-필요성- 인용되지 않은 중괄호 확장 [1]3 개의 인수로 확장됩니다 {...} .'...' 토큰 토큰포함하기 때문입니다.

  • 따라서 셸에서 따옴표를 제거한 후 다음 3 개의 리터럴 인수가 궁극적으로에 전달됩니다grep .

    • --include=*.html
    • --include=*.php
    • --include=*.htm

[1]보다 정확하게 는 괄호 확장 의 구문 관련 부분 만 인용 해제해야합니다. 목록 요소 는 여전히 개별적으로 인용 될 수 있으며 중괄호 확장 후 원치 않는 글 로빙을 초래할 수있는 글 로빙 메타 문자를 포함하는 경우 여야합니다. 이 경우에는 필요하지 않지만 위의 내용은 다음과 같이 쓸 수 있습니다.
'--include=*.'{'html','php','htm'}


1
이 게시물에 감사드립니다. 훌륭한 게시물은 질문에 답할뿐만 아니라 새로운 것을 가르쳐줍니다! 이것은 POSIX를 준수해야하는 내용을 작성하는 우리에게 특히 유용합니다. Mac OS X을 사용하는 사람은 누구나 여기를 참조하십시오!
sabalaba

@sabalaba :이 말을 들으니 기쁘지만 분명합니다. 중괄호 확장은 POSIX와 호환되지 않지만 실행되는 bash모든 플랫폼에서 bash작동합니다.
mklement0

9

큰 따옴표를 제거해보십시오.

grep --include=*.{html,php,htm} pattern -R /some/path

@tianyapiaozi 시도 grep --include=\*.{html,php,htm} pattern -R /some/path. 그것은 나를 위해 일했습니다.
Hyunjun 김

4

작동하지 않습니까?

  grep pattern  /some/path/*.{html,php,htm} 

별로. 파일 수도 하위 디렉토리의 하위 디렉토리에 상주하여
tianyapiaozi

2

이 시도. -r은 재귀 검색을 수행합니다. -s는 파일을 찾을 수 없음 오류를 억제합니다. -n은 패턴이있는 파일의 줄 번호를 보여줍니다.

    grep "pattern" <path> -r -s -n --include=*.{c,cpp,C,h}

이것은 특히 나에게 가장 좋은 대답이며 -r -s -n 대신 -rsn을 넣을 수 있다고 생각합니다 (하지만 그것은 nitpicking입니다).
slim

보통 나는 -rns를 사용 합니다 . 예제의 명확성을 위해 -r -n -s :-) 도움이 돼서 다행입니다.
Pradeep

-I표준 세트에 추가 하는 것이 좋습니다 . 거의 검색되지 않는 바이너리 파일을 건너 뛰므로 효율성이 향상됩니다. 그런 다음 grep -rIns ...어쿠스틱
피 묻은

2

동일한 목적으로 작동하지만 --include옵션이 없습니다. grep 2.5.1에서도 작동합니다.

grep -v -E ".*\.(html|htm|php)"

0

명령 grep과 함께 사용find

find /some/path -name '*.html' -o -name '*.htm' -o -name '*.php' -type f 
 -exec grep PATTERN {} \+

-regex-regextype옵션도 사용할 수 있습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.