전체 파일 시스템에서 텍스트를 검색하는 방법은 무엇입니까?


53

grep 도구를 사용해야한다고 가정하면 전체 파일 시스템에서 텍스트 문자열 "800x600"을 검색하고 싶습니다.

나는 시도했다 :

grep -r 800x600 /

그러나 작동하지 않습니다.

내 명령은 텍스트 "800x600"에 대한 루트 아래의 모든 파일 / 폴더를 통해 재귀 적으로 grep하고 검색 결과를 나열해야한다고 생각합니다.

내가 무엇을 잘못하고 있지?


2
"작동하지 않습니다"라는 말은 정확히 무엇을 의미합니까? 출력, 정지 또는 많은 Permission denied오류를 인쇄하지 않습니까? 루트 또는 일반 사용자로 실행 했습니까?
alex

나는 약간의 견인력을 얻었습니다. 먼저 명령을 실행하려고하는 사용자 홈 디렉토리에있었습니다. 이제 루트로 cd / out했습니다. 다음으로 위와 동일한 명령을 시도했는데 Permission denied 오류가 많이 발생합니다. 이제 sudo grep -r 800x600 /을 시도한 다음 / proc / sysrq-trigger를 얻습니다. 입 / 출력 오류
Level1Coder

흠, 왜 작동하지 않는지 모르겠다. 를 수행하여 액세스 오류를 무시할 수 있습니다 grep -r 800x600 / 2>/dev/null. 루트로 실행 해 볼 수도 있습니다.
Totor

답변:


64

나는 보통이 스타일의 명령을 사용 grep하여 여러 파일 을 실행 합니다.

find / -xdev -type f -print0 | xargs -0 grep -H "800x600"

이것이 실제로하는 일은 시스템의 모든 파일 목록을 만든 다음 각 파일에 대해 grep주어진 인수와 각 파일의 이름으로 실행 하는 것입니다.

-xdev인수는 다른 파일 시스템을 무시해야한다는 것을 알려줍니다 /proc. 이는와 같은 특수 파일 시스템을 피하는 데 좋습니다 . 그러나 일반 파일 시스템도 무시합니다. 예를 들어, / home 폴더가 다른 파티션에 있으면 검색되지 않습니다 find / /home -xdev .... 말할 필요가 있습니다 .

-type f즉, 파일 만 검색하므로 디렉토리, 장치 및 기타 특수 파일은 무시됩니다 (여전히 디렉토리로 돌아가서 내부 grep파일에서 실행 grep됨). 디렉토리 자체에서는 실행 되지 않으며 어쨌든 작동하지 않습니다. 그리고 항상 출력에 파일 이름을 인쇄 -H하도록 grep지시 하는 옵션 입니다.

find파일 목록을 필터링하는 모든 종류의 옵션을 허용합니다. 예를 들어 -name '*.txt'.txt로 끝나는 파일 만 처리합니다. -size -2M2MB보다 작은 파일을 의미합니다. -mtime -5지난 5 일 동안 수정 된 파일을 의미합니다. 이들을 -a for -o for or 함께 결합하고 '('괄호 ')'를 사용 하여 표현식을 그룹화하십시오 (쉘이 해석하지 못하도록 따옴표로 묶음 ). 예를 들어 :

find / -xdev '(' -type f -a -name '*.txt' -a -size -2M -a -mtime -5 ')' -print0 | xargs -0 grep -H "800x600"

man find가능한 필터의 전체 목록을 살펴보십시오 .


2
참고 -xdev제외됩니다 모든 다른 파일 시스템이 아니라 특별한 사람을. (예를 들어, /home별도의 파티션으로 마운트 한 경우 검색되지 않습니다.)
cjm

나는 각각을 실행하려고했지만 둘 다 오류를 반환합니다.find: paths must precede expression: /
Level1Coder

1
참고 : 정규식이 필요하지 않은 경우 'fgrep'이 'grep'보다 훨씬 빠르므로 큰 트리를 검색하는 경우 큰 차이가 있습니다.
Nathan Kidd

1
당신은 거치지 않아도 xargs수행하여 어쩌면 더 나은 효율 find / -xdev -type f -exec grep -H '800x600' +.
Totor

3
아니요, 명령 +끝의 부호는 find실제로 다음과 같습니다 . 여러 인수를 사용하여 xargs하나의 grep프로세스를 생성합니다 .
Totor

14

일반적으로 시스템에서 모든 것을 실제로 검색하고 싶지는 않습니다. 리눅스는 모든 것을 위해 파일 노드를 사용하므로, 일부 "파일"은 검색하고자하는 것이 아닙니다. 예를 들어 /dev/sda첫 번째 하드 드라이브의 물리적 블록 장치입니다. 원시 디스크 장치가 아닌 마운트 된 파일 시스템을 검색하려고합니다. 또한 /dev/random읽을 때마다 임의의 데이터가 추출됩니다. 이해가되지 않는 검색. /proc파일 시스템은 귀하의 경우 문제가있다.

두 가지 중 하나를 추천합니다.

  1. 루트에서 검색하지 말고 유용한 장소 만 검색하십시오. 검색 /home하거나 /usr또는 /etcseparatly. 찾고있는 정보는 특정 유형 일 가능성이 있으므로 어쨌든 특정 폴더에있을 수 있습니다. 구성 설정은에 있어야합니다 /etc. 개인 데이터 파일은에 있어야합니다 /home. 이와 같은 주요 영역으로 검색을 제한하면 재귀 그렙 문제를 크게 줄일 수 있습니다.

  2. 사용 --exclude-dir하지 않는 문제가있는 영역 과 필요하지 않은 항목은 제외하십시오.
    grep -r --exclude-dir /proc --exclude-dir /dev --exclude-dir /tmp --exclude-dir /lost+found

마지막으로 큰 재귀 grep을 수행 할 때 몇 가지 '권한 거부'오류가 발생하는 것은 드문 일이 아닙니다. 정상적인 사용 과정에서 사용자가 읽을 수없는 파일이 있습니다. 이러한 파일이 몇 개의 홀수 파일이고 하드 드라이브 또는 전체 proc 파일 시스템의 원시 장치와 같은 것이 아니라면 오류를 무시해도됩니다. 실제로 모든 오류를 절대 절대 착륙하지 않도록 명령 줄에서 수행 할 수 있습니다.

grep -r search_string /path 2> /dev/null

3
-I이진 제외
Rahul Patil

2

간단히하기 위해 ack-grep을 제안 합니다. ack-grep더 나은 옵션 인 경우 링크는 많은 경우를 보여줍니다 .

설치 후 사용하는 방법은 다음과 같습니다.

ack-grep pattern /

이것을 추천 해 주셔서 감사하지만, 이것을 실행했는데 실제로 예상했던 검색 결과를 얻지 못했습니다. 원하는 것을 얻으려면 많은 설정을 조정해야 할 것 같습니다. 현재 Richard의 답변은 즉시 사용할 수 있습니다. 앞으로도 유용하게 보일 것입니다.
Level1Coder

1

그것을 보는 또 다른 방법은 다음과 같습니다.

grep -r /* | grep "800x600"

0

* / proc / sysrq-trigger : 입 / 출력 오류가 발생합니다

명령이 작동 중입니다. 실행중인 프로세스에서 문자열을 스캔하려고하므로이 오류가 발생합니다.

시스템 디렉토리를 제외하는 것이 좋습니다

grep -exclude-dir = {proc, sys} "800x600"/


-3

간단하게

grep -r "800x600" /

-현재 명령에서 잘못된 것은 따옴표 ""입니다. 항상 문자열 인수를 grep따옴표로 묶으십시오.


3
이것은 여기서 문제가 아닙니다. 이 특정 유형의 인수를 제공 할 때는 따옴표가 필요하지 않습니다 grep. 사용해보십시오. 문자열 "800x600"을 파일에 넣으면 grep 800x600 file제대로 작동하는 것을 볼 수 있습니다. OP에는 분명히 다른 문제가 있습니다.
slm
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.