grep을 사용하여 특정 확장자와 일치하지 않는 일부 파일을 제외하는 방법은 무엇입니까?

grep을 사용하여 특정 확장자와 일치하지 않는 일부 파일을 제외하는 방법은 무엇입니까?

OK디렉토리에서 해당 단어가 포함된 모든 줄을 반복적으로 출력하고 싶습니다 . 하지만 결과에서 일부 확장자를 제외해야 합니다.

*~
*.map
*.js except *.debug.js

나는 시도했다:

grep -r --exclude={*~,*.map} "OK" /some/dir

결과에서 디버그가 아닌 파일을 모두 제거하는 방법을 모르겠습니다 .js.

답변1

다음을 통해 grep삭제 하고 싶습니다.

grep -r --exclude={\*~,\*.map} "OK" bar/ | grep -vP '(?<!debug)\.js'

일치를 반대로 하고 -v패턴과 일치하지 않는 행을 인쇄하며 -PPerl 호환 정규식을 활성화하여 다음을 사용할 수 있습니다.부정적인 리뷰. 이 특정 정규 표현식은 .js일치합니다.아니요이전의 debug의미는 (일치를 반대로 하기 때문에) 해당 .js파일만 인쇄된다는 의미입니다.

그러나 @QuestionOverflow가 주석에서 지적했듯이 필터링이라는 의도하지 않은 부작용이 있을 수 있습니다.철사포함하고 있기 OK때문에 js파일 grep -v이름뿐만 아니라 전체 출력에 적용됩니다. 이를 방지하려면 콜론을 추가하면 됩니다( grep파일 내용과 파일 이름을 구분하는 역할).

grep -r --exclude={*~,*.map} "OK" bar/ | grep -vP '(?<!debug).js:'

입력 줄에 가 포함되어 있거나 foo.js:파일 이름에 가 포함되어 :있으면 다른 접근 방식을 사용하십시오.

grep -Tr --exclude={*~,*.map} "OK" bar/ | grep -vP '(?<!debug).js\t'

파일 이름과 파일 내용 사이에 탭 문자가 인쇄되도록 합니다 -T. 따라서 정규식 끝에 grepa를 추가하면 줄의 내용이 아닌 파일 이름만 일치합니다.\t

아직,사용find어쨌든 그것은 아마도 더 의미가 있을 것입니다.

답변2

find파일을 찾고 결과를 파이프하는 데 사용하는 것 xargs:

$ find . -type f \! -name "*~" \
                 \! -name "*.map" \
                 \! \( -name "*.js" -and \! -name "*.debug.js" \) \
         -print0 | xargs -0 grep "OK"

이것은 모든 파일을 검색합니다아니요*~" ", " *.map" 또는 " 와 일치 하지만 " *.js는 일치하지 않습니다 *.debug.js.

이 방법을 사용하면 find매우 복잡한 규칙을 쉽게 검색할 수 있으며 , 이 접근 방식을 사용하면 실수로 double 을 삭제한 경우 발생할 수 있는 잘못된 긍정을 방지할 수 있습니다 grep.

답변3

우리는 함께 zsh할 수 있습니다:

setopt extendedglob
grep OK some/dir/**/^(*~|*.map|(^*debug).js)

물론, 매개변수 목록이 너무 길지 않다고 가정하고, 이 경우 언제든지 다음을 수행할 수 있습니다.

printf '%s\0' some/dir/**/^(*~|*.map|(^*debug).js) | xargs -0 grep OK

답변4

출력 순서가 약간 어긋나도 괜찮다면(정렬할 수 있다면):

grep -r --exclude={*~,*.map,*.js} "OK" /some/dir **/*.debug.js

이를 위해서는 쉘이 **재귀 와일드카드를 지원해야 합니다. zsh는 이 작업을 즉시 수행하고, bash는 실행한 후에 수행하고 shopt -s globstar, ksh93은 실행한 후에 수행합니다 set -o globstar.

쉘 지원 이 없으면 **두 가지 grep 명령을 사용할 수 있습니다.

grep -r --exclude={*~,*.map,*.js} "OK" /some/dir
grep -r --include=*.debug.js "OK" /some/dir

관련 정보