perl在binmode中以不同的偏移量搜索和删除

时间:2013-02-09 20:15:08

标签: perl seek vary

这是我写的剧本。

#usr/bin/perl
use warnings;


open(my $infile, '<', "./file1.bin") or die "Cannot open file1.bin: $!";
binmode($infile);
open(my $outfile, '>', "./extracted data without 00's.bin") or die "Cannot create extracted data without 00's.bin: $!";
binmode($outfile);

local $/; $infile = <STDIN>;
   print substr($infile, 0, 0x840, '');
   $infile =~ s/\0{16}//;
   print $outfile;

我在perl中加载一个二进制文件。 我已经能够在某些偏移量上寻找和修补,但我想要做的是,现在能够找到“00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00”的任何实例(16个字节?)并将其从文件中删除,但是没有少于16个字节。比我想要离开的还要少。在某些文件中,00开始的偏移量将处于不同的偏移量,但如果我正确思考,如果我只能搜索00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00并删除它的任何实例,那么偏移量无关紧要00是在。我会先从特定的偏移量中提取数据,然后搜索文件并从中删除00。我已经可以提取我需要的特定偏移量,我只需要打开提取的文件并删除00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

EF 39 77 5B 14 9D E9 1E 94 A9 97 F2 6D E3 68 05
6F 7B 77 BB C4 99 67 B5 C9 71 12 30 9D ED 31 B6 
AB 1F 81 66 E1 DD 29 4E 71 8D 54 F5 6C C8 86 0D 
5B 72 AF A8 1F 26 DD 05 AF 78 13 EF A5 E0 76 BB 
8A 59 9B 20 C5 58 95 7C E0 DB 44 6A EC 7E D0 10 
09 42 B1 12 65 80 B3 EC 58 1A 2F 92 B9 32 D9 07 
96 DE 32 51 4B 5F 3B 50 9A D1 09 37 F4 6D 7C 01 
01 4A A4 24 04 DC 83 08 17 CB 34 2C E5 87 26 C1 
35 38 F4 C4 E4 78 FE FC A2 BE 99 48 C9 CA 69 90 
33 87 09 A8 27 BA 91 FC 4B 77 FA AB F5 1E 4E C0        I want to leave everything from
F2 78 6E 31 7D 16 3B 53 04 8A C1 A8 4B 70 39 22 <----- here up
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <----- I want to prune everything
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00        from here on
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00<---- this IS the end of the file, and
                                                     just need to prune these few rows
                                                     of 00's

从上面的示例中说“F2 78 6E”,在另一个文件中偏移0x45000 BUT ,00 00将以不同的偏移量开始,我怎么能编码这样00 00's就会被修剪掉。在我打开的任何文件中? 如果我需要更具体,请问。 好像我到目前为止一直偷看文件,直到我打了一个很长的00 00字符串,然后修剪任何剩余的行。这有道理吗? 我想要做的就是在文件中搜索00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00的任何实例并删除/剪枝/截断它。我想保存除了00的所有内容

编辑#2 这样做了:

open($infile, '<', './file1') or die "cannot open file1: $!";
binmode $infile;
open($outfile, '>', './file2') or die "cannot open file2: $!";
binmode $outfile;

local $/; $file = <$infile>;
$file =~ s/\0{16}//g;
print $outfile $file;


close ($infile);
close ($outfile);

感谢您ikegami的所有帮助和耐心:)

1 个答案:

答案 0 :(得分:4)

不要从文件中删除。你必须

  1. 复制没有不需要的位的文件,或
  2. read文件的其余部分,seek返回,print覆盖不需要的位,然后truncate文件。
  3. 我选择了选项1.

    $ perl -e'
       binmode STDIN;
       binmode STDOUT;
       local $/; $file = <STDIN>;
       $file =~ s/\0{16}//;
       print $file;
    ' <file.in >file.out
    

    我正在将整个文件加载到内存中。任何一个选项都可以在块中完成,但它会使事情变得复杂,因为你的NUL可以跨越两个块。


    在一个措辞不佳的更新中,您似乎要求避免更改第一个0x840字节。两种解决方案:

    $ perl -e'
       binmode STDIN;
       binmode STDOUT;
       local $/; $file = <STDIN>;
       substr($file, 0x840) =~ s/\0{16}//;
       print $file;
    ' <file.in >file.out
    
    $ perl -e'
       binmode STDIN;
       binmode STDOUT;
       local $/; $file = <STDIN>;
       print substr($file, 0, 0x840, '');
       $file =~ s/\0{16}//;
       print $file;
    ' <file.in >file.out