Perl один лайнер для поиска смещения в файле

#perl #binaryfiles #one-liner

Вопрос:

Есть ли способ указать чтение в байтах файла, которые находятся в позиции/смещении в двоичном файле из командной строки? (т. Е. однострочные), например

 perl -ne <...seek n bytes into file... do stuff...> inputfile
 

Я этого не видел и пробовал использовать seek, sysseek и т. Д.

просто хочу поэкспериментировать с pack и unpack путем чтения в байтах длиной при разных смещениях внутри файла.

Обновить

В дополнение к принятому ответу я просто хочу добавить следующий эквивалентный ответ, но (для меня) его легче запомнить прочитать

 perl -lne 'BEGIN{$/=undef, $offset=1, $len=2} print unpack("H*", substr($_, $offset, $len))' input
 

Обновление 2
Для выполнения шестнадцатеричных дампов выполняются следующие работы

 perl -0777 -ne '(printf "0xx ", $_) for (unpack "C*", substr($_, 0x1, 0x2))' input
 

Ответ №1:

 perl -M5.010 -0777ne'say unpack("N", substr($_, 0x20, 4))' inputfile
 

Вы используете -n , который считывает строку файла в $_ . В двоичных файлах нет строк, поэтому мы будем использовать -0777 , чтобы сообщить Perl, что весь файл обрабатывается как строка. Не будет работать в Windows, так как произойдет перевод CRLF.


Для фактического поиска,

 perl -M5.010 -MFcntl=SEEK_SET -e'
   open(my $fh, "<:raw", $ARGV[0]) or die $!; 
   seek($fh, 0x20, SEEK_SET) or die $!;
   local $/ = 4;
   length( my $buf = <$fh> ) == 4 or die "Error";
   say unpack("N", $buf);
' inputfile
 

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

Комментарии:

1. Отлично! На мобильном банкомате, но я приму, как только я сяду за компьютер и смогу протестировать.

2. Есть ли способ разместить пространство между каждым блоком распаковки в выходных данных? $=" " это не работало на меня. Я хочу получить вывод в стиле hexdump.

3. Может быть, как-то использовать? split