수백 개의 PHP 파일이있는 사이트에서 클래스 선언을 찾고 있습니다. grep을 사용하여 현재 폴더와 하위 폴더에서 어떻게 할 수 있습니까?
cd
폴더를 테스트 한 다음
grep -r 'class MyClass' *.php
수백 개의 PHP 파일이있는 사이트에서 클래스 선언을 찾고 있습니다. grep을 사용하여 현재 폴더와 하위 폴더에서 어떻게 할 수 있습니까?
cd
폴더를 테스트 한 다음
grep -r 'class MyClass' *.php
답변:
를 사용하는 경우 현재 디렉토리-r
만 재귀 적으로 검색하려고합니다 .
grep -r 'class MyClass' .
위의 마침표에 유의하십시오.
당신이 말한 grep
것은 모든 *.php
파일 이나 디렉토리 를 재귀 적으로 검색하기를 원했지만 .php 확장자로 끝나는 디렉토리가 없을 것입니다. 위의 방법은 검색을 수행하는 가장 간단한 방법이지만 다른 유형의 파일도 포함합니다.이 파일에는 .svn 디렉토리가있을 때 특히 문제가됩니다. 다른 파일 형식이 많지 않은 경우 위의 것만으로도 충분하며 제대로 작동합니다.
대부분의 grep에는 검색 할 수있는 파일 확장자를 지정할 수있는 방법이 없으므로 일반적으로 find와 함께 find를 사용하십시오.
find <startDir> -iname '*.php' -exec grep 'class[ \t]*MyClass' {} \;
-iname
grep의 일부 버전은 대소 문자를 구분하지 않는 파일 이름 검색을 원하지만 GNU 이외의 find 변형은 지원하지 않으므로 -name
대신 사용할 수 있습니다 .
-exec
위 의 옵션은 모든 파일에 대해 grep을 호출하는 부작용이 있으므로 비용이 많이 듭니다.
여전히 다른 버전의 grep +
은 실행 파일의 호출 횟수를 줄이기 위해 인수를 함께 추가하도록 지시 하는 a 를 지원합니다 .
find <startDir> -iname '*.php' -exec grep 'class[ \t]*MyClass' {} + \;
호출을 줄이기 위해 자주 권장되는 방법은 xargs를 사용하여 grep을 가능한 한 수 있지만 필요한만큼 여러 번 실행하는 것입니다.
find <startDir> -iname \*.php | xargs grep "class[ \t]*MyClass"
xargs
grep을 명령 줄에서 지원되는 최대 개수의 인수까지 전달할 수있을만큼 똑똑하지만 위 변형은 공백과 같은 특정 문자를 잘 처리하지 못합니다. 예를 들어 파일 이름 grep이 'file.php'인 경우 'the'를 인수로 받고 'file.php'를 인수로 받으면 둘 다 찾을 수 없습니다. 대신 우리는 다음을 사용합니다.
find <startDir> -iname \*.php -print0 | xargs -0 grep "class[ \t]*MyClass"
print0
와 -0
함께 작업하고 사용 인수는 인수가 완전히 명확하게 식별되도록 널 문자 하였다.
다음에 공백이 두 개 이상 class
있거나 탭이있는 경우 정규식을 변경하여 더 많은 문자를 허용 할 수 있습니다.class[ \t]*MyClass
StackOverflow에 대한 이 게시물 에는 다른 예가 있으며 .svn 디렉토리와 같은 특정 디렉토리를 제외하는 방법을 보여줍니다.
아마도 대소 문자를 구분하지 않고 공백을 허용하고 grep이 현재 디렉토리에서 원하는 파일 패턴의 인스턴스를 찾지 못하면 종료됩니다. 시작 위치를 알고 있어야하며 일치하는 파일이 없으면 시작 경로가 생성되지 않습니다.
원하는 확장자의 파일이 하나 이상 있으면 egrep -ir을 사용할 수 있습니다. find
와 xargs
(당신이 .inc, .PHP를 검색하려는 경우 예를 들어, 및 통해서 PHP 파일 만) 단일 평면 (그러나 매우 큰) GREP이에 실패 디렉토리 및 추가 예선과 그들의 힘을 보여줍니다. 그러나 그것은 내 경험에서 상당히 편의성과 속도를 잃습니다. 인간이 작성한 클래스 선언의 경우 큰 문제는 공백입니다. 따라서 grep 대신 egrep을 사용하십시오. 추가 속도는 LC_ALL = C입니다. 편의를 위해 종종 다음을 사용합니다.
LC_ALL=C egrep -irn "class[ ]*myclass([ ]|\n)" * | egrep "\.(inc|php[35]?)"
-i -- case insensitive
-r -- recursive for all file pattern (here *)
-n -- include the line number
LC_ALL=C -- search in ASCII, not in utf8, this is much faster.
[ ]* -- match any number of spaces before the class name
([ ]|\n) -- match a space or newline after the classname
이것은 여전히와 같은 주석과 일치 할 수 // class myclass exists in file
있지만 상대적으로 작은 주석을 찾고... | fgrep -v '//'
egrep 파일 패턴에보다 복잡한 파일 마스크 (예 : 대부분의 .inc 및 .php 파일을 잡기 위해)를 포함 할 수도 있습니다.
egrep "pattern" *.[ip]*
첫 번째 옵션을 사용하면 매우 빠르며 대부분 PHP 파일로 제한됩니다.
HTH
grep -r
않는 것에 대해 말하고 싶을 수도 있습니다.