Dividindo um arquivo binário grande em seções determinadas por padrões de contexto

5

Eu tenho um arquivo grande (2 GB) que se parece com isso:

^%%-=-=-=-=-=-=-=-=-=-=-=-=-=-%%^
<binary data>
^%%-=-=-=-=-=-=-=-=-=-=-=-=-=-%%^ 
<binary data>
^%%-=-=-=-=-=-=-=-=-=-=-=-=-=-%%^
<binary data>
...

As linhas ^%%-=-=-=-=-=-=-=-=-=-=-=-=-=-%%^ são separadores. Os segmentos binários são grandes. Existem cerca de cinquenta deles no arquivo.

Estou tentando extrair as partes binárias desse arquivo. Cada segmento binário precisa entrar em seu próprio arquivo.

Eu tentei usar csplit ,

csplit --digits=2 --prefix=out stu.ear '/\^%%-=-=-=-=-=-=-=-=-=-=-=-=-=-%%\^/'

mas recebeu a seguinte saída e dois arquivos out?? ,

1
2097951144

Existe uma ferramenta para este trabalho (uma implementação csplit que funciona com arquivos binários, talvez?)

    
por Gilles 01.07.2013 / 02:48

3 respostas

3

Os seguintes itens funcionarão:

      awk '/\^%%-=-=-=-=-=-=-=-=-=-=-=-=-=-%%\^/{n++}{print >"out" n ".ear" }
    
por 01.07.2013 / 03:56
5

Eu escrevi uma pequena ferramenta python para fazer isso. link

csplitb.py --prefix X --suffix Y --number Z XXXXXXXX input-file.extension
X = Nome no início do nome do arquivo de saída
Y = Extensão de arquivo de saída desejada
Z = Número de dígitos usados para diferenciar arquivos de saída
XXXXXXXX = Iniciando hexadecimal de cada arquivo binário a ser separado do arquivo de entrada
input-file.extension = O arquivo que está sendo dividido

Exemplo: csplitb.py --prefix photo --suffix .png --number 4 89504e47 block-file.raw

Saída:

photo0000.png
photo0001.png
photo0002.png
.............
    
por 15.11.2013 / 02:21
1

Você disse ao csplit para dividir o arquivo em um local, na primeira ocorrência do texto ^%%-=-=-=-=-=-=-=-=-=-=-=-=-=-%%^ . Então, naturalmente, você tem duas partes: uma que contém o primeiro byte do arquivo (existe uma nova linha ou um espaço em branco antes do primeiro separador?) E uma que contém tudo, desde o primeiro separador em diante.

Se você quiser dividir em arquivos separados, terá que repetir o padrão quantas vezes quiser, menos um. Portavelmente, você precisa contar as peças.

csplit --digits=2 --prefix=out stu.ear '/\^%%-=-=-=-=-=-=-=-=-=-=-=-=-=-%%\^/'"{$(grep -c '\^%%-=-=-=-=-=-=-=-=-=-=-=-=-=-%%\^' stu.ear)}"

O GNU csplit tem uma extensão que permite repetir um padrão por um número indefinido de vezes:

csplit --digits=2 --prefix=out stu.ear '/\^%%-=-=-=-=-=-=-=-=-=-=-=-=-=-%%\^/ {*}'

Mas isso não faz o que você quer, porque o separador está incluído na saída. Você pode removê-lo dos arquivos depois; seria um pouco mais fácil se você organizasse os separadores no final dos arquivos, usando % em vez de / como o delimitador padrão (portanto, csplit … '%\^\%\%-=-=-=-=-=-=-=-=-=-=-=-=-=-\%\%\^% {*}' ). Mas você também pode se resignar ao fato de que o csplit, embora fofo, tem um caso de uso muito restrito, e o seu não se encaixa. Use uma ferramenta mais adequada como awk .

    
por 02.07.2013 / 01:39

Tags