根据字符串拆分二进制文件

Split binary file based on string

我有 170 个 1GB 的二进制文件,每次找到特定的 ASCII 字符串时我都想将它们拆分。其中一些字符串也有换行符。

csplit seams 是完成此任务的完美工具,但它不适用于二进制文件。

问题

如果我将搜索字符串转换为hex/binary,是否使问题更容易解决,所以它是二进制数据中的二进制搜索?

如果没有,我如何拆分基于 ASCII 字符串的二进制文件,其中一些文件有换行符?

您可以将输入记录分隔符 $/ 更改为您要拆分的特定搜索字符串(默认情况下,它是一个换行符)。然后当您读取输入文件时,将每条记录打印到一个新的唯一文件中:

#!/usr/bin/perl

use strict;
use warnings;

# change the input record separator to whatever string you want
$/ = "SOME STRING";

my $file_num = 0;
while (my $data = <>) {
  chomp $data; # remove input record separator
  my $file = "file." . ++$file_num;
  open my $fh, '>', $file or die "can't open file: $file: $!\n";
  print $fh $data;
  close $fh;
}

除了二进制文件通常包含不会出现在文本文件中的数据之外,二进制文件没有任何特别之处,而且打印出来时看起来也不好看。它们仍然是必须理解的八位字节序列,大多数体面的语言都可以让你做到这一点。

举个例子可能会有帮助。

您没有描述要用作分隔符的字符串,也没有说明读取每个块后要对其执行的操作,所以这是一个 Perl 程序,它读取1GB 的原始文件,以 specific ASCII string 结尾的块,一次一个地写出到一个新文件中。所以它相当笨拙地复制文件。

use strict;
use warnings;

open my $fh, '<:raw', '1GBfile' or die $!;
local $/ = 'specific ASCII string';

open my $out_fh, '>:raw', 'new1GBfile' or die $!;
select $out_fh;

print while <$fh>;

close $out_fh or die $!;

根据您对文件中的数据执行的操作,您可能会发现 File::Map 有用