Perl:在特定字符串后分割混合文本和二进制文件

时间:2019-06-01 16:14:26

标签: perl text binaryfiles

我有一些文件以unix分隔的文本行开头,然后切换到二进制文件。文本部分以特定字符串结尾,后跟换行符。之后是二进制。

我需要将文本部分写入一个文件,然后将其余的二进制数据写入另一个文件。这是我到目前为止的内容,但我仍然坚持如何切换到二进制文件并编写其余部分。

abcToTestDir() {
        folderName=${1%_*}
        testFolderPath="$testfilespath$folderName"
        abcFilePath="$abcpath$folderName/$1"
        testFilePath="$testFolderPath/$1"

        mkdir -p $testFolderPath
        cp $abcFilePath $testFilePath
}

1 个答案:

答案 0 :(得分:1)

最简单的方法可能是对所有内容使用二进制I / O。这样,我们就不必担心在半途中切换文件模式,并且在Unix上,文本模式和二进制模式之间也没有任何区别(除非涉及编码,但是这里我们只想复制字节)。

根据文件的纯文本部分的大小,我们可以逐行处理它,也可以一次将其全部读入内存。

#!/usr/bin/perl
use strict; 
use warnings;

my ($inputfilename, $outtextfilename, $outbinfilename) = @ARGV;

open my $in_fh, '<:raw', $inputfilename
    or die "$0: can't open $inputfilename for reading: $!\n";

open my $out_txt_fh, '>:raw', $outtextfilename
    or die "$0: can't open $outtextfilename for writing: $!\n";

open my $out_bin_fh, '>:raw', $outbinfilename
    or die "$0: can't open $outbinfilename for writing: $!\n";

# process text part
while (my $line = readline $in_fh) {
    print $out_txt_fh $line;
    last if $line =~ m{</FileSystem>};
}

# process binary part
while (read $in_fh, my $buffer, 4096) {
    print $out_bin_fh $buffer;
}

此版本的代码逐行处理文本部分,并以4096字节为块处理二进制部分(不考虑内部缓冲)。

或者,如果标记文本部分结尾的字符序列正好是"</FileSystem>\n",我们可能会显得有些厚脸皮:

# process text part
{
    local $/ = "</FileSystem>\n";
    if (my $line = readline $in_fh) {
        print $out_txt_fh $line;
    }
}

我们暂时将行尾标记从"\n"切换到"</FileSystem>\n",并读取包含所有文本部分的单个“行”。假设文本部分足够小,可以舒适地放入内存中。脚本的其余部分相同。