Ich habe eine SQLite3-Datenbank. Eine Spalte hat den Typ TEXT und enthält Blobs, die ich als Datei speichern möchte. Das sind gezippte Dateien.
Die Ausgabe des Befehls sqlite3 db.sqlite3 ".dump"
lautet:
INSERT INTO "data" VALUES(1,'objects','object0.gz',X'1F8B080000000000000 [.. a few thousands of hexadecimal characters ..] F3F5EF')
Wie kann ich die Binärdaten aus der SQLite-Datei über die Befehlszeile in eine Datei extrahieren?
Da sqlite3
keine binären Daten direkt ausgeben kann, müssen Sie die Daten in einen Hexdump konvertieren. Verwenden Sie cut
, um die Hex-Ziffern aus dem Blob-Literal zu extrahieren, und verwenden Sie xxd
(Teil des Pakets vim
), um den Hexdump wieder in eine Binärdatei zu konvertieren:
sqlite3 my.db "SELECT quote(MyBlob) FROM MyTable WHERE id = 1;" \
| cut -d\' -f2 \
| xxd -r -p \
> object0.gz
Mit SQLite 3.8.6 oder höher enthält die Befehlszeilen-Shell die Erweiterung fileio
, die die Funktion writefile
implementiert. :
sqlite3 my.db "SELECT writefile('object0.gz', MyBlob) FROM MyTable WHERE id = 1"
Ich musste einige kleine Änderungen an der Antwort von CL vornehmen, damit es für mich funktioniert:
Die Struktur für den Befehl, den er verwendet, enthält nicht den Datenbanknamen.
sqlite3 mydatabase.sqlite3 "Select quote(BlobField) From TableWithBlod Where StringKey = '1';" | ...
Die Art, wie er den Befehl cut
verwendet, funktioniert auf meinem Computer nicht. Der richtige Weg für mich ist:
cut -d "'" -f2
Der letzte Befehl wäre also etwa so:
sqlite3 mydatabase.sqlite3 "Select quote(BlobField) From TableWithBlod Where StringKey = '1';" | cut -d "'" -f2 | xxd -r -p > myfile.extension
Und in meinem Fall:
sqlite3 osm-carto_z14_m8_m.mbtiles "select quote(images.tile_data) from images where images.tile_id = '1';" | cut -d "'" -f2 | xxd -r -p > image.png
In meinem Fall verwende ich "hex" anstelle von "quote", um ein Bild aus der Datenbank abzurufen, und es ist kein "Ausschneiden" in der Befehlszeile erforderlich. Zum Beispiel:
sqlite3 fr.db "select hex(bmp) from reg where id=1" | xxd -r -p > 2.png