을(를) 사용하여 한 번에 모든 디렉토리를 검색하는 데 문제가 있습니다 grep
. 다음 명령을 사용할 때:
find . -name "*.txt" | xargs grep texthere
시간이 오래 걸리고 "해당 파일이나 디렉터리가 없습니다"라는 오류가 발생합니다.
왜 이런 일이 발생하고 이보다 쉬운 일은 없습니까 grep
? 아니면 잘못된 명령을 사용하고 있습니까?
답변1
GNU grep이 있는 경우 grep 자체는 @Ouroborus에서 제안한 대로 재귀적으로 검색할 수 있는 "-r" 옵션을 지원합니다.
불행하게도 grep이 SunOS와 같은 옵션을 지원하지 않는 경우 대신 다음 명령을 사용할 수 있습니다.
find . -name "*.txt" -exec grep -n your_pattern {} /dev/null \;
/dev/null
grep을 실행할 때마다 두 개의 파일(*.txt와 /dev/null과 일치하는 파일)이 제공되어 검색 중인 파일 이름을 강제로 인쇄하도록 하는 까다로운 작업이 추가되었습니다 . 그리고 의 범위를 구체화하기 위해 -type f
의 옵션을 추가할 수 있습니다 .find
find
답변2
에서와 같이이 답변, 다음을 수행하는 것이 더 나을 것입니다.
grep -rnw '/path/to/somewhere/' -e "pattern"
-r
또는-R
재귀적이거나-n
줄 번호이고-w
스탠드는 전체 단어와 일치합니다.-l
(소문자 L)을 추가하여 일치하는 파일의 파일 이름을 제공할 수 있습니다.
답변3
/
권한에 대한 오류가 발생한다면(그렇다고 말하지는 않지만) 루트 디렉터리( ) 또는 모든 파일을 읽을 수 있는 권한이 없는 경로에 있는 것 같습니다 . 예를 들어 in /etc
또는 in /var
. 하지만 시간이 엄청나게 오래 걸린다고 말씀하셨기 때문에 저는 첫 번째 가정(루트 디렉터리) 쪽으로 더 기울고 있습니다.
절대적으로 검색하고 싶다면모두에 있는 파일전체시스템, 당신이하고있는 것보다 거의 옳습니다. 그것~ 할 것이다무엇을 하든 오랜 시간이 걸립니다. 검색할 파일이 엄청나게 많습니다.
를 사용하여 find
볼 파일의 양을 좁힐 수 있습니다.
현재 당신은
$ find . -name "*.txt" | xargs grep texthere
일반 텍스트 파일에만 관심이 있는 것으로 보이므로 다른 유형의 파일(실행 파일)은 제외할 수 있습니다.
$ find / -type f \! -perm -o=x -name "*.txt" | xargs grep texthere
.
나는 여기 로 바꿨다 /
. 왜냐하면 그곳이 내가 있는 곳이기 때문이다.생각하다당신은 그렇습니다 (내가 틀렸다면 정정하십시오). 나는 또한 내가 원하는 것을 지정하고 있습니다파일( -type f
) 그것은실행 불가능( \! -perm -o=x
) ( !
쉘이 이상한 일을 하지 않도록 이스케이프해야 합니다).
이제 우리가 할 수 있는 일이 몇 가지 더 있습니다. 하나는 안전 문제이고 다른 하나는혹시속도가 조금 향상됩니다.
일부 파일 이름에는 공백이 있거나 일반적으로 파일 이름에 원하지 않는 기타 이상한 문자가 있을 수 있습니다. 이를 적절하게 전달할 수 있도록 우리는 않습니다 find
.grep
$ find / -type f \! -perm -o=x -name "*.txt" -print0 | xargs -0 grep texthere
이( )는 각 파일 이름이 공백 문자가 아닌 문자( ) -print0
로 구분됨을 의미합니다 . 그리고 이를 -구분된 파일 이름 으로 수신하기 위한 해당 옵션 은 입니다 .nul
\0
xargs
nul
-0
"해당 파일이나 디렉터리가 없습니다"라는 오류가 발생하는 것은 두 가지 옵션을 사용하지 않기 때문입니다.
속도는 fgrep
. grep -F
이는 검색 문자열이 정규 표현식이 없는 일반 텍스트 문자열인 경우 사용해야 하는 것과 정확히 동일한 유틸리티입니다 .
따라서 일반 텍스트 문자열이 있고 전체 시스템의 모든 단일 파일에서 이를 찾으려는 경우:
$ find / -type f \! -perm -o=x -name "*.txt" -print0 | xargs -0 fgrep texthere
권한 문제... 분명히 읽을 수 없는 파일이 있을 것입니다. 다음을 실행 find
하고 fgrep
앞에 sudo
추가할 수 있습니다.
$ sudo find ... | xargs -0 sudo fgrep texthere
-perm
또는 다른 플래그를 만들려고 시도할 수도 있지만 find
(입력할 수 없는 디렉터리를 무시하도록 설정할 수도 있음) 시간이 너무 많이 걸리고 명령줄이 엄청나게 길어질 수 있으므로 여기서는 그렇게 하지 않겠습니다.
아니면 그냥 sudo -s
루트 셸을 가져와 거기에서 실행할 수도 있습니다. 하지만 일반적으로 사람들은 자신의 시스템이 root
.
또 다른 솔루션명령 을 사용하여 전체 시스템의 locate
모든 파일을 찾는 것 입니다. .txt
이 locate
명령은 파일 계층 구조를 검색하지 않고 대신 데이터베이스(보통 매일 업데이트되므로 업데이트되지 않음)를 사용합니다.모두파일이 있을 수 있습니다). 데이터베이스에는 모든 사용자가 액세스할 수 있는 디렉터리의 파일만 포함되어 있으므로 자신의 디렉터리에서 읽기 권한을 제거한 경우 해당 파일은 해당 디렉터리에 존재하지 않습니다.
따라서 위의 명령을 거의 동일한 find
명령으로 바꾸십시오.locate
$ locate '*.txt' -0 | xargs -0 fgrep texthere
옵션 -0
(또는 --null
일부 시스템에서는) --print0
은 의 옵션 에 해당합니다 find
.