Cách nhanh chóng để xác định xem một tệp có phải là cơ sở dữ liệu SQLite không


8

Tôi đang tìm cách để xác định các loại tệp trong một thư mục có hàng ngàn tệp. Tên tệp không tiết lộ nhiều và không có phần mở rộng, nhưng là các loại khác nhau. Cụ thể, tôi đang cố gắng xác định xem một tệp có phải là cơ sở dữ liệu sqlite không.

Khi sử dụng filelệnh, nó sẽ xác định loại 2-3 tệp mỗi giây. Đây có vẻ là một cách tốt để giải quyết vấn đề, ngoại trừ nó quá chậm.

Sau đó, tôi đã thử mở từng tệp bằng sqlite3 và kiểm tra xem tôi có bị lỗi không. Bằng cách đó, tôi có thể kiểm tra 4-5 tệp mỗi giây. Tốt hơn nhiều, nhưng tôi nghĩ rằng có thể có một cách tốt hơn để làm điều này.


Để tham khảo thời gian, hãy filechạy trên 2115 tệp mà không có tùy chọn đặc biệt nào 0m0.117s user 0m0.078s sys 0m0.044sdành cho tôi
Glenn Plas

Câu trả lời:


7

2-3 tệp mỗi giây được thử nghiệm với tôi filedường như rất chậm. filethực sự thực hiện một số thử nghiệm khác nhau để thử và xác định loại tệp. Vì bạn đang tìm kiếm một loại tệp cụ thể (sqlite) và bạn không quan tâm đến việc xác định tất cả các loại khác, bạn có thể thử nghiệm trên một tệp sqlite đã biết để xác định thử nghiệm nào thực sự xác định nó. Sau đó, bạn có thể loại trừ những người khác bằng cách sử dụng -ecờ và chạy với tập tin đầy đủ của bạn. Xem trang người đàn ông :

 -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.

Chỉnh sửa: Tôi đã thử một số bài kiểm tra bản thân mình. Tóm lược:

  1. Áp dụng lời khuyên của tôi với các cờ phù hợp có thể tăng tốc filekhoảng 15%, cho các thử nghiệm để xác định sqlite. Đó là một cái gì đó, nhưng không phải là sự cải thiện lớn mà tôi mong đợi.
  2. Kiểm tra tập tin của bạn là rất chậm. Tôi đã làm 500 trên một máy tiêu chuẩn trong thời gian bạn làm 2-3. Bạn có đang sử dụng phần cứng chậm hoặc kiểm tra các tệp khổng lồ, chạy phiên bản cổ filehoặc ...?
  3. Bạn phải giữ bài kiểm tra 'mềm' để xác định thành công một tệp là sqlite.

Đối với tệp DB sqlite 16 MB, tôi đã làm:

#!/bin/bash
for  i in {1..1000}
do
    file sqllite_file.db | tail > out
done

Thời gian trên dòng lệnh:

~/tmp$ time ./test_file_times.sh; cat out

real    0m2.424s
user    0m0.040s
sys 0m0.288s
sqllite_file.db: SQLite 3.x database

Thử các loại thử nghiệm khác nhau loại trừ và giả sử xác định được thực hiện dựa trên một thử nghiệm duy nhất, đó là thử nghiệm 'mềm' (tức là tra cứu tệp ma thuật) xác định tệp. Theo đó, tôi đã sửa đổi filelệnh để loại trừ tất cả các thử nghiệm khác:

file -e apptype -e ascii -e encoding -e tokens -e cdf -e compress -e elf -e tar sqllite_file.db | tail > out

Chạy 1000 lần này:

~/tmp$ time ./test_file_times.sh; cat out

real    0m2.119s
user    0m0.060s
sys         0m0.280s
sqllite_file.db: SQLite 3.x database

Cảm ơn câu trả lời công phu. Tôi cũng phát hiện ra rằng thử nghiệm 'mềm' là bắt buộc. Tắt các thử nghiệm khác (trên 10000 lần lặp) cho kết quả gần như tương tự.
dmars

Sau khi nhận xét của bạn rằng thời gian thực hiện quá chậm, tôi bắt đầu đặt câu hỏi về quy trình chạy nó và tôi phát hiện ra rằng sqlite=$(echo $filetype | grep -c SQLite)yêu cầu ít nhất là cùng lúc với lệnh tập tin. Và tôi có một số lệnh khác làm chậm thủ tục. Điều thú vị là, chạy sqlite3 $filename ".schema"vẫn nhanh hơn hai lần so với lệnh tập tin.
dmars

4

Nếu bạn xem: http://www.sqlite.org/fileformat.html , định dạng SQLite bắt đầu bằng chuỗi "Định dạng SQLite 3 \ 000". Dường như với tôi rằng bạn có thể kiểm tra head -c 16tệp để kiểm tra định dạng. Tôi hy vọng điều này sẽ nhanh hơn sau đó sử dụng các công cụ có mục đích chung hơn.


3

Nếu bạn xem filemô tả ma thuật của các tệp sqlite, nó sẽ tìm SQLite format 3hoặc ** This file contains an SQLiteở đầu tệp.

Vì vậy, bạn có thể tạo một tệp ma thuật chỉ bằng các kiểm tra đó (và vô hiệu hóa các kiểm tra dựng sẵn như trong giải pháp @ire_and_curses) hoặc thực hiện kiểm tra theo cách thủ công:

case $(head -c 31 < "$file") in
  ("** This file contains an SQLite"*) echo sqlite 2;;
  ("SQLite format 3"*) echo sqlite 3;;
esac

Không hiệu quả lắm vì nó chạy một headtệp. Với một chút nỗ lực của bạn, có lẽ bạn có thể làm điều đó trong perl, để đọc 31 byte đầu tiên của một số tệp trong một lệnh gọi perl.


Cảm ơn. Hóa ra rằng cố gắng mở bằng sqlite3 vẫn là cách nhanh hơn. Về hiệu năng, vấn đề chủ yếu là với các lệnh khác trong quy trình mà tôi chưa xem xét.
dmars
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.