何千ものファイルを含むフォルダでファイルの種類を確認する方法を探しています。ファイル名は多くの情報を明らかにせず、拡張子はありませんが、形式が異なります。特に、ファイルがsqliteデータベースであることを確認したいと思います。
このfile
コマンドを使用すると、1秒あたり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バイトを読み取ることができます。