“찾기”를 사용하여 특정 파일 이름을 무시하는 방법?


143

내가 가장 좋아하는 BASH 명령 중 하나는 다음과 같습니다.

find . -name '*.*' -exec grep 'SearchString' {} /dev/null \;

지정된 SearchString에 대해 현재 디렉토리와 그 아래에있는 모든 파일의 내용을 검색합니다. 개발자로서 이것은 때때로 유용합니다.

그러나 현재 프로젝트와 코드베이스의 구조로 인해 ".svn"이 포함 된 디렉토리 또는 그 아래에있는 파일이나 그에 해당하는 파일을 검색하지 않음으로써이 BASH 명령을 더욱 발전시키고 싶습니다. ".html"로 끝남

그래도 찾기 종류의 MAN 페이지가 혼란 스럽습니다. -prune을 사용해 보았는데 이상한 동작이있었습니다. .html 페이지 만 건너 뛰려고 (시작하기 위해) 시도했습니다.

find . -wholename './*.html' -prune -exec grep 'SearchString' {} /dev/null \;

내가 바랐던 행동을 얻지 못했습니다. 나는 자두의 요점을 놓칠 수 있다고 생각합니다. 너희들이 나를 도울 수 있습니까?

감사


1
그냥 fyi : 내장 findbash 명령이 아니라 별도의 프로그램입니다
WakiMiko

1
다음으로 파일 내부를 검색 할 수 있습니다grep -rl 'SearchString'
emanuele

@emanuele 안녕하세요, 슈퍼 유저 (및 스택 교환 네트워크)에 오신 것을 환영합니다. 이것은 제가 물었던 질문이며, 2 1/2 년 전에 답변되었습니다. 일반적으로 질문에 대한 답변을 추가하려면 의견 대신 맨 아래로 스크롤하여 답변하십시오. 이 질문에 이미 승인 된 답변 (녹색 확인 표시가있는 답변)이 있으므로 답변에 많은 관심을 기울이지는 않을 것입니다. 참고로
Cody S

1
안녕하세요, 귀하의 질문에 대한 답변이 아닙니다. 프리앰블에서 언급했듯이 find파일 내부를 검색 하는 데 사용하는 팁 입니다.
emanuele

2
FWIW -name '*.*'모든 파일을 찾지는 못합니다 . .이름 이있는 파일 만 사용합니다 ( *.*일반적으로 DOS 방식이지만 유닉스에서는 일반적으로 사용됩니다 *). 실제로 모두 일치 시키려면 인수를 모두 제거하십시오 find . -exec .... 또는 grep을 파일에만 적용하고 디렉토리를 건너 뛰려면을 수행하십시오 find . -type f -exec ....
Stefan

답변:


197

find의 부정 (!) 기능을 사용하여 특정 이름을 가진 파일과 일치하지 않을 수 있습니다.

find . ! -name '*.html' ! -path '*.svn*' -exec grep 'SearchString' {} /dev/null \;

따라서 이름이 .html로 끝나거나 경로의 .svn을 포함하면 일치하지 않으므로 exec가 실행되지 않습니다.


1
여전히 -name '을 지정해야합니다 . '어딘가에? 협상 전후에 그렇게 하시겠습니까?
Cody S

*.*일치 하는 의도가 .?를 포함하는 파일과 만 일치하도록 하시겠습니까? Find는 name지시어 가 없으면 모든 파일과 일치 하므로 위의 내용은 html 및 svn을 제외한 모든 파일과 일치합니다.
Paul

5
나는 당신이 -wholename '*.svn*'오히려 원한다고 생각합니다 -name.
fuenfundachtzig

2
예, .svn디렉토리가 검색 결과에서 제외되도록합니다.
fuenfundachtzig

1
@Noumenon ! -name '.'.찾기 결과에서 제외해야 합니다.
Paul

11

나는 오랫동안 같은 문제를 겪었고 다른 상황에 적용 할 수있는 몇 가지 솔루션이 있습니다.

  • ack-grep기본적으로 버전 제어 디렉토리 및 임시 파일을 건너 뛰는 일종의 "개발자 grep"입니다 . 이 페이지에서는 특정 파일 형식 만 검색하는 방법과 고유 한 파일 형식을 정의 하는 방법에 대해 설명합니다 .man
  • grep의 자체 옵션 --exclude--exclude-dir옵션을 사용하면 파일 globs단일 디렉토리 를 건너 뛸 수 있습니다 (불행히도 디렉토리를 globbing하지 않음).
  • find . \( -type d -name '.svn' -o -type f -name '*.html' \) -prune -o -print0 | xargs -0 grep ... 작동하지만 위의 옵션은 장기적으로 번거 로움이 적습니다.

9

다음 find명령은 이름이 포함 된 디렉토리를 프룬합니다. 디렉토리로 .svn내려 가지 않더라도 프룬 된 경로 이름이 인쇄됩니다 ... ( -name '*.svn'원인!) ..

다음 grep -d skip을 통해 디렉토리 이름을 필터링 할 수 있습니다. 이 입력은 "디렉토리 이름"입력을 자동으로 건너 뜁니다.

GNU grep을 사용하면 -H대신에 사용할 수 있습니다 /dev/null. 약간의 부작용으로 : 예를 들어 \+보다 훨씬 빠를 수 있습니다 \;. 1000000 한 줄 파일을 사용하여 \;그것을했다 4m20s를 사용하여, \+그것은 단지했다 1.2s .

다음 방법은 xargs대신을 사용 -exec하고 \n파일 이름 에 줄 바꿈이 없다고 가정 합니다 . 여기에 사용 된 xargs것처럼 find 's와 거의 동일 \+합니다.

xargs에 입력 구분 기호를 변경하여 연속적인 공백이 포함 된 파일 이름을 통과 할 수 '\n'-d옵션을 선택합니다.

이 이름이 디렉토리 제외 포함을 .svn 하고 끝나지 않는 파일 만 greps .html.

find . \( -name '*.svn*' -prune  -o ! -name '*.html' \) |
   xargs -d '\n' grep -Hd skip 'SearchString'

1
\+-exec 조치 의 변형 을 지적 해 주셔서 감사합니다 . 사소한 측면 문제에 대한 만세!
Christian Long

물론, +쉘에 특수 문자가 아니기 때문에 쉘에 입력 할 필요가 없습니다 \.
Scott
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.