Замена двоичного кода
Я пытался сделать замену sed
в двоичном файле, однако я начинаю считать, что это невозможно. По сути, я хотел сделать следующее:
sed -bi "s/\(\xFF\xD8[[:xdigit:]]\{1,\}\xFF\xD9\)/\1/" file.jpg
Логика, которую я хочу достичь, заключается в следующем: просканировать двоичный файл до шестнадцатеричного кода FFD8
, продолжить чтение до FFD9
и сохранить только то, что было между ними (отбрасывает мусор до и после, но включает FFD8
и FFD9
в качестве сохраненной части файла)
Есть ли хороший способ сделать это? Даже если вы не используете sed
?
EDIT: Я просто играл и нашел самый чистый способ сделать это IMO. Я знаю, что это выражение grep будет жадным.
hexdump -ve '1/1 "%.2x"' dirty.jpg | grep -o "ffd8.*ffd9" | xxd -r -p > clean.jpg
Ответы
Ответ 1
bbe является "sed для двоичных файлов" и должен работать более эффективно для больших двоичных файлов, чем hexdumping/restore.
Пример использования:
$ bbe -e 's/original/replaced/' infile > outfile
Дополнительная информация на странице .
Ответ 2
Is there a good way to do this
да, конечно, используйте инструмент редактирования изображений, например, инструмент ImageMagick (поиск в сети для linux jpeg, exif editor и т.д.), который знает, как редактировать метаданные jpg. Я уверен, что вы найдете один инструмент, который вам подходит. Не пытайтесь делать это с трудом.:)
Ответ 3
sed может это сделать, но это может быть сложно. Здесь Python script делает то же самое (обратите внимание, что он редактирует файл на месте, что я предполагаю, что вы хотите сделать на основе вашего sed script):
import re
f = open('file.jpeg', 'rb+')
data = f.read()
match = re.search('(\xff\xd8[0-9A-fa-f]+)\xff\xd9', data)
if match:
result = match.group(1)
f.seek(0)
f.write(result)
f.truncate()
else:
print 'No match'
f.close()
Ответ 4
Кроме того, этот Perl может работать (не проверен, caveat emptor)... если Python не установлен:)
open(FILE, "file.jpg") || die "no open $!\n";
while (read(FILE, $buff, 8 * 2**10)) {
$content .= $buff;
}
@matches = ($content =~ /(\xFF\xD8[:xdigit:]+?\xFF\xD9)/g;
print STDOUT join("", @matches);
Вам нужно добавить binmode(FILE); binmode(STDOUT);
в DOS или VMS после вызова open()
- не требуется в Unix.