印刷できない文字を16進値に置き換える

印刷できない文字を16進値に置き換える

深刻な破損したSqliteファイルがあります。すべてをSQLファイルにダンプして新しいファイルにロードする一般的な方法は機能しませんが、16進エディタを使用すると回復する必要があるデータがあることがわかります。

このパターンに出会いました。

vimはASCII文字のみを表示し、別のバイトをバイナリデータとして扱うことはできますか?

viに印刷できない文字を16進数で表示するようにします。

すごいですね、お知らせします。

14>>07>>テイスティ・マクタイソン氏[Eメール保護]

しかし、表示しながらファイルに書き込む方法はありますか?

したがって、viがバッファに<14>という16進値で表示することは、実際にそれをテキストファイルの対応する文字に変更します。

viで正規表現の検索と置換を行うことでこれを実行できますが、印刷できない各文字に対して一度に1つずつ実行する必要があります。これはかなり大きなファイルです。

後で<14> <07>を16ビット整数として扱う予定ですが、まずそれを実際の文字としてテキストファイルに入れることができるはずです。

事前にありがとう

ベストアンサー1

xxd付属のコンテンツを表示して、vim列に16進データと印刷可能文字をダンプできます。 16進数を編集する場合は、データを再プッシュしてxxd -r2進数に戻すことができます。

ただし、最終目標を見ると、より強力なものが必要になる場合がありますperl。たとえば、私はこれの専門家ではありませんが、次のことが役に立ちます。

#!/usr/bin/perl
# https://unix.stackexchange.com/a/452784/119298
use strict;
sub fn{ 
    my ($ch,$ch2,$rest) = @_;
    return sprintf("%5u",(ord($ch)<<8)|ord($ch2)).$rest;
}
my $data = join("",<>);
$data =~ s/(.)(.)([a-zA-Z][ -~]{10,})/fn($1,$2,$3)/ge;
print $data;

stdinのすべてのデータを変数として読み取り、ランダムな$data2s/.../.../gバイト文字とアルファベット文字(azとAZの範囲)、その後に10文字以上の印刷可能文字(チルダまでの範囲、C言語環境の仮定)をペアで連結します。これらの部分は()3つの別々の部分に分割されてキャプチャされ、関数呼び出しに置き換えられますfne結局これが意味するところです。

この関数は、単に整数に変換され、変更されていない3番目の引数に関連付けられた2バイトの文字列印刷を返します。

助けるためにあなたが望むことをするより簡単なバージョンがあります。印刷されない文字を<..>

my $data = join("",<>);
$data =~ s/([^ -~\n])/sprintf("<%02x>",ord($1))/ge;
print $data;

^ここのパターンは比較的簡単です。つまり、意味のある印刷できない文字(および改行文字)の範囲です。いいえ。単純なsqliteファイルを見ると、テキストデータの直前の文字が通常印刷可能な文字であることがわかりました。だから、文字開始文字をテストするパターンを使用しましたが、より良い経験的な方法を使用することをお勧めします。

おすすめ記事