다음을 사용하여 파일을 찾을 수 있다는 것을 알고 있습니다 find
. find . -type f -name 'sunrise'
결과 예:
./sunrise
./events/sunrise
./astronomy/sunrise
./schedule/sunrise
또한 파일의 파일 형식을 결정할 수 있다는 것도 알고 있습니다. file sunrise
결과 예:
sunrise: PEM RSA private key
하지만 파일 유형별로 파일을 찾는 방법은 무엇입니까?
예를 들어, my-find . -type f -name 'sunrise' -filetype=bash-script
:
./astronomy/sunrise
./schedule/sunrise
답변1
Unix 시스템의 "파일 형식"일반 파일, 디렉토리, 명명된 파이프, 문자 특수 파일, 심볼릭 링크 등 find
해당 옵션을 사용하여 필터링할 수 있는 파일 형식은 다음과 같습니다 -type
.
유틸리티 find
자체는 "셸 스크립트", "JPEG 이미지 파일" 또는 기타 파일을 구별할 수 없습니다.일반 파일 형식. 그러나 이러한 유형의 데이터는 file
파일 콘텐츠 유형을 결정하기 위해 파일 자체 내의 특정 서명을 살펴보는 유틸리티로 구별할 수 있습니다 .
다양한 유형의 데이터 파일에 레이블을 지정하는 일반적인 방법은MIME 유형, file
파일의 MIME 유형을 결정할 수 있습니다.
일반 파일의 MIME 유형을 감지하고 이를 사용하여 쉘 스크립트만 찾으려면 file
with를 사용하십시오 .find
find . -type f -exec sh -c '
case $( file -bi "$1" ) in (*/x-shellscript*) exit 0; esac
exit 1' sh {} \; -print
또는 bash
,
find . -type f -exec bash -c '
[[ "$( file -bi "$1" )" == */x-shellscript* ]]' bash {} \; -print
해당 이름의 스크립트만 탐지하려면 -name sunrise
앞에 추가하세요.-exec
위의 명령은 find
현재 디렉토리 안이나 아래의 모든 일반 파일을 찾고 그러한 각 파일에 대해 짧은 인라인 쉘 스크립트를 호출합니다. 스크립트는 file -bi
발견된 파일에서 실행되고 명령 출력에 strings 가 포함된 경우 종료 상태 0으로 종료됩니다 /x-shellscript
. 출력에 이 문자열이 포함되어 있지 않으면 0이 아닌 종료 상태로 종료되어 find
다음 파일로 즉시 계속됩니다. 파일이 쉘 스크립트인 것으로 확인되면 find
명령은 계속해서 파일의 경로 이름을 출력합니다( -print
마지막 경로는 다른 작업으로 대체될 수도 있음).
이 file -bi
명령은 파일의 MIME 유형을 출력합니다. Linux(및 대부분의 다른 시스템)의 쉘 스크립트의 경우 이는 다음과 같습니다.
text/x-shellscript; charset=us-ascii
이 유틸리티의 약간 오래된 버전이 설치된 시스템에서는 file
다음과 같은 문제가 발생할 수 있습니다.
application/x-shellscript
공통 비트는 /x-shellscript
부분 문자열입니다.
file -bI
macOS에서는 대신 사용해야 합니다 file -bi
.이유(이 -i
옵션은 완전히 다른 기능을 수행합니다). macOS의 출력은 Linux 시스템의 출력과 유사합니다.
발견된 각 쉘 스크립트에 대해 몇 가지 사용자 정의 작업을 수행하시겠습니까? 위 명령 -exec
대신 다른 스크립트를 사용할 수도 있지만 다음을 수행할 수도 있습니다.-print
find
find . -type f -exec sh -c '
for pathname do
case $( file -bi "$pathname" ) in
*/x-shellscript*) ;;
*) continue
esac
# some code here that acts on "$pathname"
done' sh {} +
또는 bash
,
find . -type f -exec bash -c '
for pathname do
[[ "$( file -bi "$pathname" )" != */x-shellscript* ]] && continue
# some code here that acts on "$pathname"
done' bash {} +
관련된:
답변2
발견된 각 파일을 실행 file
한 다음 grep을 통해 관심 있는 결과를 얻을 수 있습니다.
# When looking for ASCII Text
find . -type f -exec file {} \; | grep "ASCII"
# or for MS Word Documents
find . -type f -exec file {} \; | grep "Microsoft Word"
잘못된 긍정 일치 수를 낮게 유지하려면 검색 패턴을 예상에 최대한 가깝게 유지하는 것이 좋습니다.
이름에 줄 바꿈이 포함된 파일은 이 방법에서 문제를 일으킬 수 있습니다.
답변3
쉘 마법을 너무 많이 포함하지 않는 더 짧은 형식:
find . -exec sh -c "file '{}' | grep -q 'pattern'" \; -print
답변4
사용된 perl
모듈 File::LibMagic
:
perl -MFile::LibMagic=:easy -MFile::Find -le '
find sub {
print $File::Find::name if
$_ eq "sunrise" and
-f and
MagicFile$_ eq "PEM RSA private key"
}, @ARGV' -- .
File::LibMagic
동일한 알고리즘과 휴리스틱을 사용하여 파일 유형을 추측 file
하지만 여기서는 모든 것이 단일 호출로 수행되므로 perl
각 파일에 대해 단일 호출을 실행하는 것보다 훨씬 효율적입니다 file
.