用十六進制數值替換不可列印的字元
我有一個嚴重損壞的 Sqlite 文件將所有內容轉儲到 sql 文件並將其載入到新文件中的常用技巧不起作用,但是使用十六進制編輯器我可以看到我需要恢復的數據在那裡
我遇到了這種模式
vim 可以只顯示 ASCII 字元,而將其他字節視為二進制數據嗎?
vi 將不可列印的字元顯示為十六進制
這很棒,會告訴我
‹14›‹07› Testy McTesterson 先生 me@example.com
但是有沒有在顯示時將其寫入文件?
因此,將 vi 在其緩衝區中顯示為 ‹14› 的十六進制值實際更改為文本文件中的那些字元
我可以在 vi 中做一個正則表達式搜尋替換來做,但是我必須一次為每個不可列印的字元做一個,這是一個非常大的文件
稍後,我計劃將‹14›‹07›處理成它應該表示的16位整數,但首先我需要能夠將這些作為真實字元放入文本文件中
提前謝謝了
您可能會查看
xxd
附帶的哪些vim
數據,並以十六進制格式轉儲數據,並在列中轉儲可列印字元。如果您編輯十六進制,您可以將數據推回xxd -r
以將其轉換回二進制。然而,看看你的最終目標,你可能需要更強大的東西
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;
它將標準輸入中的所有數據讀入變數
$data
,然後對s/.../.../g
由任意 2 個字節後跟一個字母字元(範圍 az 和 AZ)、後跟 10 個或更多可列印字元(在範圍空間到波浪號,並假設 C 語言環境)。這些部分通過 using 被擷取()
為 3 個單獨的部分,並由 function 的呼叫替換fn
。這就是e
最後的意思。該函式只返回一個字元串列印,將 2 個字節轉換為整數,並與第三個未更改的參數連接。
為了提供幫助,這裡有一個更簡單的版本,它只做你想要的,將非列印字元替換為
<..>
.my $data = join("",<>); $data =~ s/([^ -~\n])/sprintf("<%02x>",ord($1))/ge; print $data;
這裡的模式更簡單,即不可列印字元(和換行符)的範圍,
^
意思是not。在查看一個簡單的 sqlite 文件時,我發現文本數據之前的字元通常是可列印字元。這就是為什麼我使用了一個測試字母起始字元的模式,但您可能需要使用更好的啟發式方法。