수천 개의 파일이 포함된 폴더에서 파일 형식을 확인하는 방법을 찾고 있습니다. 파일 이름은 많은 정보를 드러내지 않고 확장자가 없지만 형식이 다릅니다. 특히 파일이 sqlite 데이터베이스인지 확인하려고 합니다.
이 file
명령을 사용하면 초당 2~3개의 파일 유형이 결정됩니다. 이는 문제에 대한 좋은 해결책처럼 보이지만 너무 느립니다.
그런 다음 sqlite3을 사용하여 각 파일을 열고 오류가 있는지 확인합니다. 이렇게 하면 초당 4~5개의 파일을 확인할 수 있습니다. 훨씬 낫지만 더 좋은 방법이 있을 수도 있다고 생각합니다.
답변1
초당 2-3개의 파일을 테스트하는 것은 file
느린 것 같습니다. file
실제로 파일 형식을 시도하고 결정하기 위해 수행되는 다양한 테스트가 있습니다. 하나의 특정 유형의 파일(sqlite)을 찾고 있고 다른 모든 파일을 인식하는 데는 관심이 없으므로 알려진 sqlite 파일을 실험하여 실제로 이를 인식하는 테스트를 결정할 수 있습니다. 그런 다음 해당 플래그를 사용하여 다른 파일을 제외 -e
하고 전체 파일 세트에 대해 실행할 수 있습니다. 보다매뉴얼 페이지:
-e, --exclude testname
Exclude the test named in testname from the list of tests made to
determine the file type. Valid test names are:
apptype
EMX application type (only on EMX).
text
Various types of text files (this test will try to guess the
text encoding, irrespective of the setting of the ‘encoding’
option).
encoding
Different text encodings for soft magic tests.
tokens
Looks for known tokens inside text files.
cdf
Prints details of Compound Document Files.
compress
Checks for, and looks inside, compressed files.
elf
Prints ELF file details.
soft
Consults magic files.
tar
Examines tar files.
편집하다:나는 몇 가지 테스트를 직접 시도했습니다. 요약:
file
특정 sqlite로 테스트할 때 내 제안과 올바른 플래그를 적용하면 작업 속도가 약 15% 향상될 수 있습니다. 뭔가 있긴 하지만, 제가 기대했던 엄청난 개선은 아니었습니다.- 파일 테스트가 정말 느립니다. 나는 표준 머신으로 500번을 했고 당신은 2-3번을 했습니다. 느린 하드웨어를 사용하고 있습니까? 대용량 파일을 검사하고 있습니까? 이전 버전을 실행하고 있습니까?
file
아니면...? - 파일을 sqlite로 성공적으로 식별하려면 "소프트" 테스트를 유지해야 합니다.
16MB sqlite DB 파일에 대해 다음을 수행했습니다.
#!/bin/bash
for i in {1..1000}
do
file sqllite_file.db | tail > out
done
명령줄에서의 타이밍:
~/tmp$ time ./test_file_times.sh; cat out
real 0m2.424s
user 0m0.040s
sys 0m0.288s
sqllite_file.db: SQLite 3.x database
다양한 테스트 제외를 시도하고 단일 테스트를 기반으로 결정이 내려졌다고 가정하면 파일을 식별하는 것은 "소프트"(예: 매직 파일 조회) 테스트입니다. 따라서 file
다른 모든 테스트를 제외하도록 명령을 수정했습니다.
file -e apptype -e ascii -e encoding -e tokens -e cdf -e compress -e elf -e tar sqllite_file.db | tail > out
1000번 실행:
~/tmp$ time ./test_file_times.sh; cat out
real 0m2.119s
user 0m0.060s
sys 0m0.280s
sqllite_file.db: SQLite 3.x database
답변2
당신이 보면 :http://www.sqlite.org/fileformat.html, SQLite 형식은 "SQLite 형식 3\000" 문자열로 시작됩니다. head -c 16
파일을 검사하여 형식을 확인할 수 있는 것 같습니다 . 좀 더 일반적인 도구를 사용하는 것보다 이것이 더 빠르기를 바랍니다.
답변3
sqlite 파일의 마법 설명을 보면 파일의 시작 부분에서 또는 파일을 file
찾습니다 .SQLite format 3
** This file contains an SQLite
따라서 이러한 검사만 포함하는 매직 파일을 생성하거나(@ire_and_curses 솔루션에 내장된 테스트를 비활성화함) 수동으로 검사를 수행할 수 있습니다.
case $(head -c 31 < "$file") in
("** This file contains an SQLite"*) echo sqlite 2;;
("SQLite format 3"*) echo sqlite 3;;
esac
모든 파일을 실행하므로 그다지 효율적이지 않습니다 head
. 조금만 노력하면 Perl에서 단일 Perl 호출로 여러 파일의 처음 31바이트를 읽을 수 있습니다.