Perl初学者:如何在文件中查找/替换ASCII字符?

3

我对Perl完全不熟悉,但认为它是解决我的简单任务的最佳语言。我需要将二进制文件转换为可读的内容,并找到并替换像\x00\x39这样的字符串为\x09(制表符)或类似的东西。

从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的文本文件。有需要注意的地方吗?
非常感谢任何帮助!
Gary
3个回答

7

使用 \x## 表示法:

perl -pi~ -e 's/\x00/*/g' test.txt

要将每个“特殊”字符替换为其代码(括号内),请使用/e选项:

perl -pi~ -e 's/([\x0-\x09\x11-\x1f])/"[" . ord($1) . "]"/eg' test.txt

是的,这就是我需要的;我漏掉了反斜杠 :-) - Gary Czychi

1

哇,非常感谢。我意识到这并不像我想象的那么容易。哇,Perl真的非常复杂 ;-)

这是我想出来的东西。我希望这会对某些人有所帮助。

顺便说一句:如果您有机会知道这是否也适用于Windows Perl,请告诉我。

再次感谢,

Gary

#!/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;
}

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模块(来自Perl核心)允许您通过数组访问文件的行。更改将立即保存到文件中。在foreach循环中,逐行处理文件。行进入$_,我们看不到它。正则表达式操作默认也应用于$_,因此无需写下它。


然而,我认为你的方法是错误的。在大多数情况下,你将无法仅仅逐行读取文件。可以参考perlfaq作为起点。处理二进制比纯文本处理要棘手得多,恐怕需要更多技巧。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接