我是Perl的新手,我认为这将是解决我简单任务的最佳语言。我需要将二进制文件转换为可读的内容,并且需要查找并将\x00\x39
之类的字符串替换为\x09
(tab)或类似内容。
从bash开始,我开始使用以下内容,效果很好:
perl -pi -e 's/abc/123/g' test.txt
然而,当我开始输入ascii代码时,我迷路了:
perl -pi -e 's/0x49/*/g' test.txt
perl -pi -e 's/{char(49)}/*/g' test.txt
这个命令在perl脚本中的行怎么样?我有大约几百个这样的查找/替换操作和一个500MB的文本文件。有什么警告我需要知道吗?
非常感谢您的帮助!
加里
答案 0 :(得分:7)
使用\x##
表示法:
perl -pi~ -e 's/\x00/*/g' test.txt
要用括号中的代码替换每个“特殊”字符,请使用/e
选项:
perl -pi~ -e 's/([\x0-\x09\x11-\x1f])/"[" . ord($1) . "]"/eg' test.txt
答案 1 :(得分:1)
这是我想出的。我希望这会对某人有所帮助。
BTW:如果你有机会知道这对 Windows Perl 是否也有效,请告诉我。
再次感谢,
加里
#!/usr/bin/perl
use strict;
use warnings;
my $infile = '/Users/gc/Desktop/a.bin';
my $outfile = '/Users/gc/Desktop/b.txt'; # in and out can be the same file; file will be overwritten when it already exists
my $data = read_file($infile);
# 1st batch
$data =~ s/0\x01J[\x00-\x19]/\x09AnythingYouWant\x09/g;
$data =~ s/0\x00[\x00-\x19]/\x09AnythingYouWant\x09/g;
# 2nd batch
$data =~ s/\r/\x06/g; # CR into \x06
$data =~ s/\n/\x06/g; # LF into \x06
$data =~ s/\r\n/\x06/g; # CR LF into \x06
# …
write_file($outfile, $data);
exit;
sub read_file {
my ($infile) = @_;
open my $in, '<', $infile or die "Could not open '$infile' for reading $!";
local $/ = undef;
my $all = <$in>;
close $in;
return $all;
}
sub write_file {
my ($outfile, $content) = @_;
open my $out, '>', $outfile or die "Could not open '$outfile' for writing $!";;
print $out $content;
close $out;
return;
}
答案 2 :(得分:0)
虽然在二进制文件上执行字符串替换有点奇怪,但这里是如何使用txt文件执行此操作:
use strict;
use warnings;
use Tie::File;
my @file;
tie @file, 'Tie::File', 'test.txt' or die $!;
foreach (@file) {
# your regexes go here
s/abc/123/g;
s/\0x49/*/g;
}
untie @file;
Tie::File module(来自Perl核心)允许您通过数组访问文件的行。更改将立即保存到文件中。在foreach
循环中,逐行处理文件。这些行进入$_
,我们看不到。默认情况下,正则表达式操作也应用于$_
,因此无需将其写下来。
但是,我相信你会以错误的方式解决这个问题。在大多数情况下,您将无法逐行读取文件。请参考perlfaq作为起点。处理二进制文件比我害怕的文本处理更棘手。