我已编写以下脚本,因为我需要在某些文件中进行一些清理。我有一个特定数量的十六进制字符需要更改为另一组十六进制字符(即null为空格,见下文)。我写过以下脚本,我的问题是它只替换了第一次出现而没有别的。
我已经尝试了/ g就像一个普通的sed模式,但它不起作用。有没有办法做到这一点并替换所有匹配?
(我没有使用$line =~ s/...
的原因是因为我认为它更整洁,更可维护,并且有时可能需要编辑十六进制值的其他人访问和运行此脚本被替换)。另一个原因是因为我需要将10+以上的值更改为等量,因此很难读取一个巨大的内衬。提前谢谢。
#!/usr/bin/perl
use strict;
use warnings;
my $filebase = shift || "testreplace.txt";
my $filefilter = shift || "testf";
open my $fh1, '>', 'testreplaceout';
# Iterate over file and read lines
open my $file1, '<', $filebase;
while (my $line = <$file1>)
{
chomp($line);
for ($line) {
s/\x00/\x20/g;
s/\x31/\x32/g;
}
print {$fh1} "$line \n";
}
答案 0 :(得分:0)
更新:阅读有关此答案的警告的评论。
以下一种方法可以让您在脚本顶部保留正则表达式搜索/替换列表,以便于查看和修改:
use warnings;
use strict;
my @re_list = (
['a', 'x'],
['b', 'y'],
);
while (my $line = <DATA>){
for my $re (@re_list){
$line =~ s/$re->[0]/$re->[1]/g;
}
print $line;
}
__DATA__
aaabbbccc
bbbcccddd
ababababa
输出:
xxxyyyccc
yyycccddd
xyxyxyxyx
答案 1 :(得分:0)
/g
会做你想要的。如果它似乎不起作用,请添加一些调试:
use Data::Dumper;
$Data::Dumper::Useqq = $Data::Dumper::Terse = 1;
在你的循环中:
print Dumper($line);
for ($line) {
s/\x00/\x20/g;
s/\x31/\x32/g;
}
print Dumper($line);
使用带有成对分隔符的tr可以非常易读/可维护:
$line =~ tr[\x00\x31]
[\x20\x32];
另外,请考虑添加use autodie;
答案 2 :(得分:0)
tr///
is probably your best bet here (since you are dealing with constant single character replacements). The following is a more generic solution.
my %replacements = (
'foo' => 'bar',
'bar' => 'baz',
);
my $pat = join '|', map quotemeta, keys(%replacement);
s/($pat)/$replacements{$1}/g;