답변:
나는 이것이 오래된 스레드라는 것을 알고 있지만 그것을 우연히 발견하고 find
바이너리가 아닌 파일 만 찾는 데 사용하는 매우 빠른 방법 인 내 방법을 공유 할 것이라고 생각했습니다 .
find . -type f -exec grep -Iq . {} \; -print
-I
그렙에 대한 옵션은 즉시 바이너리 파일과 무시하도록 지시 .
과 함께 옵션을 -q
즉시 확인이 매우 빠르게 진행 있도록 텍스트 파일을 일치합니다. 공백이 염려되는 경우 -print
를 a -print0
로 변경할 수 있습니다 xargs -0
(팁 @ lucas.werkmeister!).
또한 첫 번째 점은 find
OS X와 같은 특정 BSD 버전에만 필요 하지만 별칭이나 무언가에 넣으려는 경우 항상 거기에 두는 것만으로도 손상되지 않습니다.
편집 : @ruslan이 올바르게 지적했듯이은 암시 적이므로 -and
생략 할 수 있습니다.
find -type f -exec grep -Iq . {} \; -and -print
파일을 보관하는 이점이있는 것을 사용할 수도 있습니다 find
. 텍스트 파일에 대해서만 실행 -print
되는 다른 -exec
것으로 대체 할 수 있습니다. (당신이 할 수있는 경우 grep
파일 이름을 인쇄, 당신은 그들에 줄 바꿈와 파일 이름을 구별 할 수 없습니다.)
find . -type f -exec grep -Il . {} +
훨씬 빠릅니다. 단점은 다른 확장 할 수 없다는 것입니다 -exec
lucas.werkmeister 제안 @로
왜 불편한가요? 자주 사용해야하고 매번 타자하고 싶지 않은 경우 bash 함수를 정의하면됩니다.
function findTextInAsciiFiles {
# usage: findTextInAsciiFiles DIRECTORY NEEDLE_TEXT
find "$1" -type f -exec grep -l "$2" {} \; -exec file {} \; | grep text
}
그것을 넣고 .bashrc
실행하십시오.
findTextInAsciiFiles your_folder "needle text"
당신이 원할 때마다.
편집은 영업 이익의 편집을 반영하기 :
MIME 정보를 잘라내려면 MIME 정보를 필터링하는 파이프 라인에 추가 단계를 추가하면됩니다. 이것은 앞에 오는 것만 취함으로써 트릭을 수행해야합니다 :
: cut -d':' -f1
:
function findTextInAsciiFiles {
# usage: findTextInAsciiFiles DIRECTORY NEEDLE_TEXT
find "$1" -type f -exec grep -l "$2" {} \; -exec file {} \; | grep text | cut -d ':' -f1
}
file
수동 : "사용자는 디렉토리에서 읽을 수있는 모든 파일이 단어를 '텍스트'인쇄가 아는에 따라 달라집니다."
/proc/meminfo
, /proc/cpuinfo
등 텍스트 파일, 그러나 file /proc/meminfo
말한다 /proc/meminfo: empty
. '텍스트'외에 '비어 있음'을 테스트해야하는지 궁금하지만 다른 유형도 '비어 있음'을보고 할 수 있는지 확실하지 않습니다.
find . -type f -print0 | xargs -0 file | grep -P text | cut -d: -f1 | xargs grep -Pil "search"
이것은 안타깝게도 공간 절약이 아닙니다. 이것을 bash 스크립트에 넣으면 조금 더 쉬워집니다.
이것은 공간 안전입니다.
#!/bin/bash
#if [ ! "$1" ] ; then
echo "Usage: $0 <search>";
exit
fi
find . -type f -print0 \
| xargs -0 file \
| grep -P text \
| cut -d: -f1 \
| xargs -i% grep -Pil "$1" "%"
text.bin
됩니까? 2. 파일 이름에 :
?
이건 어때요:
$ grep -rl "needle text" my_folder | tr '\n' '\0' | xargs -r -0 file | grep -e ':[^:]*text[^:]*$' | grep -v -e 'executable'
파일 유형없이 파일 이름을 원하면 최종 sed
필터를 추가하기 만하면 됩니다.
$ grep -rl "needle text" my_folder | tr '\n' '\0' | xargs -r -0 file | grep -e ':[^:]*text[^:]*$' | grep -v -e 'executable' | sed 's|:[^:]*$||'
-e 'type'
마지막 grep
명령에 더 많은 옵션을 추가하여 불필요한 파일 유형을 필터링 할 수 있습니다 .
편집하다:
xargs
버전이 -d
옵션을 지원하는 경우 위의 명령이 더 간단 해집니다.
$ grep -rl "needle text" my_folder | xargs -d '\n' -r file | grep -e ':[^:]*text[^:]*$' | grep -v -e 'executable' | sed 's|:[^:]*$||'
histumness의 대답에는 두 가지 문제가 있습니다.
텍스트 파일 만 나열합니다. 실제로 요청한대로 검색하지 않습니다. 실제로 검색하려면
find . -type f -exec grep -Iq . {} \; -and -print0 | xargs -0 grep "needle text"
매우 느린 모든 파일에 대해 grep 프로세스를 생성합니다. 그렇다면 더 나은 해결책은
find . -type f -print0 | xargs -0 grep -IZl . | xargs -0 grep "needle text"
또는 간단히
find . -type f -print0 | xargs -0 grep -I "needle text"
위의 솔루션 (2.5GB 데이터 / 7700 파일)의 경우 4 초에 비해 0.2 초 밖에 걸리지 않습니다 . 즉, 20 배 더 빠릅니다 .
또한 아무도 ag, Silver Searcher 또는 ack-grep ¸를 대안으로 인용하지 않았습니다 . 이 중 하나를 사용할 수있는 경우 훨씬 더 나은 대안입니다.
ag -t "needle text" # Much faster than ack
ack -t "needle text" # or ack-grep
마지막 으로 오 탐지 (텍스트 파일로 사용되는 바이너리 파일)에 주의하십시오 . 이미 grep / ag / ack를 사용하여 오 탐지가 있었으므로 파일을 편집하기 전에 일치하는 파일을 먼저 나열하는 것이 좋습니다.
오래된 질문이지만이 정보가 여기에 대한 답변의 품질을 더할 것이라고 생각합니다.
실행 가능한 비트가 설정된 파일 을 무시할 때 다음 명령을 사용합니다.
find . ! -perm -111
재귀 적으로 다른 디렉토리에 들어 가지 않도록하려면 :
find . -maxdepth 1 ! -perm -111
파이프 가 많은 명령을 혼합 할 필요가 없으며 강력한 일반 찾기 명령 만 있으면 됩니다.
즉, 이것이 누구에게나 유용하기를 바랍니다.
1) 검색 할 파일 (~ 30k)이 너무 많기 때문에 아래 명령을 사용하여 crontab을 통해 사용할 텍스트 파일 목록을 매일 생성합니다.
find /to/src/folder -type f -exec file {} \; | grep text | cut -d: -f1 > ~/.src_list &
2) .bashrc에 함수를 만듭니다.
findex() {
cat ~/.src_list | xargs grep "$*" 2>/dev/null
}
그런 다음 아래 명령을 사용하여 검색을 수행 할 수 있습니다.
findex "needle text"
HTH :)
한 줄에 두 개 이상의 명령을 입력하는 방법을 배우려는 저와 같은 초보자를위한 확장 된 설명이 포함 된 단순화 된 버전이 있습니다.
단계적으로 문제를 작성하면 다음과 같습니다.
// For every file in this directory
// Check the filetype
// If it's an ASCII file, then print out the filename
이를 위해 세 가지 UNIX 명령 find
인 file
,,를 사용할 수 있습니다 grep
.
find
디렉토리의 모든 파일을 확인합니다.
file
파일 유형을 제공합니다. 우리의 경우 'ASCII 텍스트'의 반환을 찾고 있습니다.
grep
출력에서 'ASCII'키워드를 찾습니다. file
그렇다면 어떻게 한 줄로 묶을 수 있습니까? 이를 수행하는 방법은 여러 가지가 있지만 의사 코드 순서대로 수행하는 것이 가장 합리적이라는 것을 알았습니다 (특히 저와 같은 초보자에게).
find ./ -exec file {} ";" | grep 'ASCII'
복잡해 보이지만 분해하면 나쁘지 않습니다.
find ./
=이 디렉토리의 모든 파일을 살펴 봅니다. 이 find
명령은 '표현식'과 일치하는 파일의 파일 이름 또는 경로 뒤에 오는 모든 파일의 파일 이름을 인쇄합니다.이 경우에는 현재 디렉터리 또는./
이해해야 할 가장 중요한 것은 첫 번째 비트 이후의 모든 것이 True 또는 False로 평가된다는 것입니다. True이면 파일 이름이 인쇄됩니다. 그렇지 않은 경우 명령이 계속 진행됩니다.
-exec
=이 플래그는 다른 명령의 결과를 검색 표현식으로 사용할 수 있도록하는 find 명령 내의 옵션입니다. 함수 내에서 함수를 호출하는 것과 같습니다.
file {}
= 내부에서 호출되는 명령 find
. 이 file
명령은 파일의 파일 유형을 알려주는 문자열을 반환합니다. 정기적으로 다음과 같이 표시 file mytextfile.txt
됩니다.. 우리의 경우, 우리는 find
명령 이보고있는 파일을 사용하기를 원 하므로 {}
빈 변수 또는 매개 변수 역할을하기 위해 중괄호 를 넣습니다 . 즉, 시스템이 디렉토리의 모든 파일에 대해 문자열을 출력하도록 요청하는 것입니다.
";"
= 이것은에 의해 요구되며 명령 find
끝에있는 구두점 -exec
입니다. 를 실행하여 필요한 경우 자세한 설명은 '찾기'매뉴얼을 참조하십시오 man find
.
| grep 'ASCII'
= |
파이프입니다. 파이프는 왼쪽에있는 모든 출력을 가져 와서 오른쪽에있는 입력으로 사용합니다. find
명령 의 출력 (단일 파일의 파일 유형 인 문자열)을 가져 와서 문자열이 포함되어 있는지 테스트합니다 'ASCII'
. 그렇다면 true를 반환합니다.
이제 오른쪽에있는 표현식 find ./
은 grep
명령이 true를 반환 할 때 true를 반환합니다. 짜잔.
의 file
힘과 결합 된 멋진 유틸리티를 사용하여 매직 바이트로 파일 유형을 찾는 데 관심이 있다면 다음 과 같이 find
유용 할 수 있습니다.
$ # Let's make some test files
$ mkdir ASCII-finder
$ cd ASCII-finder
$ dd if=/dev/urandom of=binary.file bs=1M count=1
1+0 records in
1+0 records out
1048576 bytes (1.0 MB, 1.0 MiB) copied, 0.009023 s, 116 MB/s
$ file binary.file
binary.file: data
$ echo 123 > text.txt
$ # Let the magic begin
$ find -type f -print0 | \
xargs -0 -I @@ bash -c 'file "$@" | grep ASCII &>/dev/null && echo "file is ASCII: $@"' -- @@
산출:
file is ASCII: ./text.txt
범례 : $
명령을 입력하는 대화 형 쉘 프롬프트입니다.
&&
다른 스크립트를 호출하거나 인라인으로 다른 작업을 수행하기 위해 부분을 수정할 수 있습니다 . 즉, 파일에 주어진 문자열이 포함되어 있으면 전체 파일을 분류하거나 그 안에있는 보조 문자열을 찾을 수 있습니다.
설명:
find
파일 인 항목xargs
하나 개 라이너로 라인으로 각 항목을 공급 bash
명령 / 스크립트file
매직 바이트로 파일 유형을 grep
확인하고 ASCII가 존재하는지 확인한 후 &&
다음 명령이 실행 된 후에 확인 합니다.find
결과를 null
분리하여 인쇄 합니다. 공백과 메타 문자가있는 파일 이름을 이스케이프하는 것이 좋습니다.xargs
, -0
옵션을 사용하여 null
구분 하여 읽고 -I @@
각 레코드를 가져와 bash 스크립트에 대한 위치 매개 변수 / 인수로 사용합니다.--
for bash
는 그것이 bash 옵션으로 해석 될 수 있는 -
like -c
로 시작하는 경우에도 인수 인 뒤에 오는 모든 것을 보장합니다.ASCII 이외의 유형을 찾으려면 다음 grep ASCII
과 같이 다른 유형으로 바꾸십시오.grep "PDF document, version 1.4"
이건 어때요
find . -type f|xargs grep "needle text"
"needle text"
"needl text"
"needle text"
있으면 찾을 수 있습니다.
find . -type f -exec grep -Il "" {} \;
.