web-dev-qa-db-ja.com

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

何千ものファイルがあるフォルダ内のファイルタイプを判別する方法を探しています。ファイル名はあまりわかりませんし、拡張子もありませんが、種類は異なります。具体的には、ファイルがsqliteデータベースであるかどうかを判断しようとしています。

fileコマンドを使用すると、1秒あたり2〜3個のファイルのタイプが判別されます。これは、遅すぎることを除けば、問題に対処するための良い方法のようです。

次に、sqlite3で各ファイルを開いて、エラーが発生するかどうかを確認してみました。そうすれば、1秒あたり4〜5個のファイルをチェックできます。はるかに良いですが、これを行うためのより良い方法があるかもしれないと思います。

8
dmars

fileでテストされた1秒あたり2〜3ファイルは、私には非常に遅いようです。 fileは実際に、さまざまなテストを実行して、ファイルタイプを判別します。特定の種類のファイル(sqlite)を探していて、他のすべてのファイルを特定する必要がないため、既知のsqliteファイルを試して、どのテストが実際に特定するかを判断できます。次に、-eフラグを使用して他のユーザーを除外し、完全なファイルセットに対して実行できます。 manページ を参照してください:

 -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. 正しいフラグを使用して私のアドバイスを適用すると、sqliteを判別するためのテストでfileを約15%高速化できます。これは何かですが、私が期待した大きな改善ではありません。
  2. あなたのファイルテストは本当に遅いです。あなたが2-3をやった時に私は標準的なマシンで500をやった。遅いハードウェアを使用しているのか、巨大なファイルをチェックしているのか、古いバージョンの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
7
ire_and_curses

http://www.sqlite.org/fileformat.html を見ると、SQLiteフォーマットは文字列 "SQLite format 3\000"で始まります。ファイルのhead -c 16をチェックしてフォーマットをチェックできるように思えます。これは、より汎用的なツールを使用するよりも高速であると思います。

4
Winston Ewert

fileのsqliteファイルの魔法の説明を見ると、どちらかの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でそれを実行して、1回のPerl呼び出しで複数のファイルの最初の31バイトを読み取ることができます。

3