특정 경로에서 파일을 제외하고`grep`을 실행하십시오. . 내가보고있는 것은

./test/main.cpp검색 에서 파일을 제외하고 싶습니다 .

내가보고있는 것은 다음과 같습니다.

$ grep -r pattern --exclude=./test/main.cpp
./test/main.cpp:pattern
./lib/main.cpp:pattern
./src/main.cpp:pattern

파이프 및 필터 배열에서 여러 명령을 사용하여 원하는 출력을 얻을 수 있지만 grep기본적으로 원하는 것을 이해하는 인용 / 이스케이프가 있습니까?



답변

grep 다른 디렉토리에 동일한 이름을 가진 파일이 더있는 경우 특정 디렉토리의 파일에 대해이 작업을 수행 할 수 없습니다. 대신 find를 사용하십시오.

find . -type f \! -path './test/main.cpp' -exec grep pattern {} \+


답변

나는 그것이 GNU에서 가능하다고 생각하지 않습니다 grep. 파이프는 필요하지 않습니다.

find:

find . ! -path ./test/main.cpp -type f -exec grep pattern {} +

zsh:

grep pattern ./**/*~./test/main.cpp(.)

(숨겨진 파일은 제외하고 .git, .svn …도 제외합니다.)


답변

나는 “잃어버린 예술”이라는 책을 쓸 수있었습니다 xargs. find ... -exec … ';출시 각 파일에 대한 그렙 (그러나와 변형 -exec … +하지 않습니다). 요즘 우리는 CPU 사이클을 낭비하고 있습니다. 왜 그렇지 않습니까? 그러나 성능과 메모리 및 전원이 문제인 경우 xargs를 사용하십시오.

find . -type f \! -path 'EXCLUDE-FILE' -print0 | xargs -r0 grep 'PATTERN'

GNU의 find의는 -print0것이다 NUL출력 및 -terminate xargs-0입력으로 해당 형식 옵션 명예를. 이렇게하면 파일에 재미있는 문자가 있으면 파이프 라인이 혼동되지 않습니다. 이 -r옵션은 find아무것도 찾지 못할 경우 오류가 없는지 확인 합니다.

이제 다음과 같은 작업을 수행 할 수 있습니다.

find . -type f -print0 | grep -z -v "FILENAME EXCLUDE PATTERN" |
  xargs -r0 grep 'PATTERN'

GNU grep ‘s -z는 xargs ‘와 동일한 기능을 수행합니다 -0.


답변

귀하의 경우에는 find지원 -path2008 년 POSIX에 추가하지만 여전히 솔라리스에서 누락되었다 :

find . ! -path ./test/main.cpp -type f -exec grep pattern /dev/null {} +

답변

기록을 위해, 내가 선호하는 접근 방식은 다음과 같습니다.

grep pattern $(find . -type f ! -path './test/main.cpp')

grep명령의 시작 부분에 를 유지하면 이것이 더 명확하다고 생각합니다 grep. 또한 색상 강조 표시를 비활성화하지 않습니다 . 어떤 의미 find에서, 명령 대체에서 사용 하는 것은 기능의 (제한된) 파일 검색 서브 세트를 확장 / 대체하는 방법입니다 grep.


나에게 find -exec구문 은 일종의 비전입니다. 한 가지 복잡한 점 find -exec은 (때로는) 다양한 문자를 피할 필요가 있다는 것입니다 (특히 \;Bash에서 사용되는 경우 ). 익숙한 상황에 적용하기 위해 다음 두 명령은 기본적으로 동일합니다.

find . ! -path ./test/main.cpp -type f -exec grep pattern {} +
find . ! -path ./test/main.cpp -type f -print0 |xargs -0 grep pattern

하위 디렉토리제외 하려면 와일드 카드를 사용해야 할 수도 있습니다. 나는 완전히 여기 스키마를 이해하지 않는 – 비밀에 대한 이야기 :

grep pattern $(find . -type f ! -path './test/main.cpp' ! -path './lib/*' )

스크립트에서 사용하기위한find 기반 솔루션 을 일반화 하기위한 추가 참고 사항 : grep명령 행에는 -H/ --with-filename옵션 이 포함되어야합니다 . 그렇지 않으면의 검색 결과에 파일 이름이 하나만있는 상황에서 출력 형식이 변경됩니다 find. grep의 기본 파일 검색 ( -r옵션 포함)을 사용하는 경우 필요하지 않은 것 같으므로 주목할 만합니다 .

…하지만 /dev/null검색 할 첫 번째 파일로 포함 시키는 것이 더 좋습니다 . 이렇게하면 두 가지 문제가 해결됩니다.

  • 검색 grep할 파일이 하나 있으면 두 개가 있다고 생각하고 다중 파일 출력 모드를 사용합니다.
  • 검색 할 파일이 없으면 grep하나의 파일이 있다고 생각하고 stdin을 기다리지 않습니다.

최종 답변은 다음과 같습니다.

grep pattern /dev/null $(find . -type f ! -path './test/main.cpp')