Можете ли вы использовать sed или perl -pe для удаления детали из двоичного файла? - PullRequest
2 голосов
/ 26 июня 2011

Я пытаюсь удалить части из двоичного файла, которые находятся между строками ANSI "stringstart" и "stringend".Возможно ли это сделать с помощью sed или perl -pe?

Я думаю о каком-то решении Regex, но не знаю, как его написать или насколько хорошо regex работает с двоичными файлами.

Ответы [ 3 ]

6 голосов
/ 26 июня 2011

sed предназначен для обработки текстовых файлов, а не двоичных файлов, хотя в наши дни это различие обычно менее значимо, чем когда-то.Самая большая проблема заключается в том, что текстовые файлы не содержат нулевых байтов (байтов со значением 0), а двоичные файлы содержат, и многие функции обработки C-строк останавливаются на первом нулевом байте.sed также читает «строки», отмеченные символами новой строки.В результате двоичные файлы могут заканчиваться длинными строками.Наконец, нет никакой гарантии относительно взаимного расположения маркеров начала и конца строки относительно новых строк.Все эти характеристики делают sed менее подходящим для этой работы, чем Perl.

В Perl мне очень хотелось бы выкинуть файл в память, используйте соответствующее регулярное выражение для извлечения данных из памятиизображение, а затем запишите результат обратно в соответствующее место.

perl -e 'local($/); $data = <>; $data =~ s/stringstart(.*?)stringend//gms; print $data'

Сейчас протестировано - тестовые данные, созданные с использованием:

#!/usr/bin/env perl
use strict;
use warnings;

sub full_set
{
    foreach my $i (0..255) { printf "%c", $i; }
}
sub random_set
{
    my($n) = @_;
    foreach my $i (0..$n) { printf "%c", int(rand(255)); }
}

full_set;
random_set(1024);
printf("stringstart");
full_set;
random_set(512);
full_set;
printf("stringend");
random_set(256);

Сценарий удаляет 1045 символов из ввода- что соответствует 'stringstart', 'stringend' (20) + 2 * 256 + 513 (поскольку random_set(512) печатает 513 символов).

Обратите внимание, что основной скрипт будет считывать все файлы в память одновременно.Если вы хотите, чтобы он обрабатывал один файл за раз, вам придется работать немного усерднее;он, вероятно, перестает быть однострочным.

2 голосов
/ 27 июня 2011

Альтернативный подход:

perl -pi -we'BEGIN{$/="stringend"} chomp and s/stringstart.*//s' your_binary_file
0 голосов
/ 26 июня 2011

Вы можете создать регулярное выражение, которое убивает все символы, не определенные после ^ внутри [] . Например

cp /bin/ls ./binfile
file binfile
binfile: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped

Сделайте на нем перл-пирог:

perl -pi -e 's/[^[a-zA-Z0-9_+\n]//g' binfile

Затем посмотрите на двоичный файл:

file binfile
binfile: ASCII text, with very long lines

Вам, очевидно, придется добавить больше к этой команде, поскольку она избавит от нескольких других потенциальных символов. Но это должно начать вас.

...