ファイルがSQLiteデータベースであるかどうかをすばやく確認する方法

ファイルがSQLiteデータベースであるかどうかをすばやく確認する方法

何千ものファイルを含むフォルダでファイルの種類を確認する方法を探しています。ファイル名は多くの情報を明らかにせず、拡張子はありませんが、形式が異なります。特に、ファイルが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.

編集する:私はいくつかのテストを自分で試しました。要約:

  1. file特定のsqliteでテストするときに私の提案と正しいフラグを適用すると、作業速度が約15%向上する可能性があります。何かありましたが、私が期待していた大きな改善はありませんでした。
  2. ファイルテストは本当に遅いです。私は標準的なマシンで500回を行い、あなたは2-3回をしました。遅いハードウェアを使用していますか?大容量ファイルをスキャンしていますか?以前のバージョンを実行していますか?fileそれとも…?
  3. ファイルを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バイトを読み取ることができます。

関連情報