#binary
#двоичный
Вопрос:
У меня есть двоичный файл, содержащий некоторые пути к файлам. Если путь начинается с определенной строки, остальная часть пути к файлу [x20-x7f]
должна быть замаскирована, оставляя общую структуру и размер файла нетронутыми!
Итак, со списком путей для поиска это:
/usr/local/bin/
/home/joe/
Затем подобное вхождение в двоичные данные:
^@^@^@^@/home/joe/documents/hello.docx^@^@^@^@
Должно быть изменено на это:
^@^@^@^@/home/joe/********************^@^@^@^@
Каков наилучший способ сделать это? Есть ли способ в sed, perl или awk? Или мне нужно написать программу на C или PHP, где я нахожу строку и записываю strlen()
количество символов маски вместо нее?
Ответ №1:
perl
является хорошим выбором для работы с двоичными данными. Для sed
и awk
только реализации GNU обычно могут работать с двоичными данными, другие будут перегружены нулевым байтом или длинными последовательностями между двумя символами новой строки или строками без завершения.
perl -pi.back -e 's{(/usr/local/bin|/home/joe)/K[x20-x7f] }{
$amp; =~ s/./*/rg}ge' binary-file
Вам понадобится не слишком старая версия perl
для /r
флага (возвращает результат подстановки вместо применения его к переменной) и K
(сбросьте начало соответствующей строки).
По умолчанию perl -p
работает с одной строкой за раз, поскольку символ новой строки не является частью [x20-x7f]
, это нормально.
Комментарии:
1. Это решение сработало прямо из коробки! Отлично подходит для анонимизации личной информации в файлах журналов. (Там не хватает
/
bin
, но это детали!)2. @forthrin. Спасибо, теперь я убрал конечную
/
строку из чередования, чтобы она применялась к обоим путям.
Ответ №2:
Вот некоторый код perl, который работает, хотя я уверен, что его можно оптимизировать. Это фильтр, поэтому он считывает все стандартные $data
значения, затем для каждой строки в массиве @dirs
он заменяет шаблон. Однако замена — это не фиксированная строка, а вызов функции replace($dir,$1)
, который вычисляется из-за e
модификатора команды substitute .
#!/usr/bin/perl
use strict;
sub replace{
my ($dir,$rest) = @_;
$rest =~ s/./*/g;
return $dir.$rest;
}
my @dirs = ('/usr/local/bin/','/home/joe/');
my $data = join("",<STDIN>);
foreach my $dir (@dirs){
$data =~ s|$dir([x20-x7f] )|replace($dir,$1)|ge;
}
print $data;
Функции присваивается 2 аргумента: каталог и захваченная часть шаблона. Он возвращает их объединенными после замены каждого символа в захваченной строке.