Você pode ver xxd
, que vem com vim
, e despeja dados em caracteres hexadecimais e imprimíveis em colunas. Se você editar o hexadecimal, poderá enviar os dados de volta por xxd -r
para convertê-los novamente em binário.
No entanto, olhando para o seu objetivo final, você provavelmente precisará de algo mais poderoso como perl
, no qual não sou especialista, mas você pode achar útil o seguinte:
#!/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;
Ele lê todos os dados do stdin na variável $data
e, em seguida, faz um substituto global ( s/.../.../g
) para o padrão
consiste em quaisquer 2 bytes seguidos por um caractere alfabético (o intervalo a-z e A-Z), seguido por 10 ou mais caracteres imprimíveis (no espaço de intervalo para til e assumindo uma localidade C). Essas partes são capturadas usando ()
em 3 partes separadas e substituídas por uma chamada da função fn
. Isso é o que significa o e
no final.
A função simplesmente retorna uma seqüência de caracteres dos 2 bytes convertidos em um inteiro, concatenados com o terceiro parâmetro inalterado.
Para ajudar, aqui está uma versão mais simples que só faz o que você deseja, substituindo os caracteres não imprimíveis por <..>
.
my $data = join("",<>);
$data =~ s/([^ -~\n])/sprintf("<%02x>",ord($1))/ge;
print $data;
Aqui, o padrão é mais simples, ou seja, o intervalo de caracteres não imprimíveis (e nova linha), com ^
significando não . Ao olhar para um arquivo sqlite simples, eu encontrei o caractere imediatamente antes dos dados do texto serem frequentemente um caractere imprimível. É por isso que usei um padrão que testa um caractere inicial alfabético, mas você provavelmente precisará usar uma melhor heurística.