多个模式匹配和替换

时间:2015-06-30 09:34:50

标签: regex perl awk sed grep

如何从文件中提取模式并使用文件中的新模式替换多个模式? 例如: 让我们说模式文件是pattern.txt,如下所示,有2,000行。

a  
b   
d  
e  
f  
....  
...  
...  

替换pattens的文件是replace.txt,其中包含:

a,1    
b,3  
c,5  
d,10  
e,14   
....  
...  
...   

文件patterns.txt的预期最终文件内容是:

a,1    
b,3    
d,10  
e,14  
....  
...  
... 

3 个答案:

答案 0 :(得分:3)

来自命令行的Perl,

perl -i -pe'
  BEGIN{ local (@ARGV, $/, $^I) =pop; %h = split /[\s,]+/, <> }
  s| (\S+)\K |,$h{$1}|x
' pattern.txt replace.txt

它将第二个文件($/)的内容包含到undef中,并暂时禁用就地编辑($^I为undef),在空格/逗号上拆分字符串并填充{{1}以键/值方式散列。然后,对于第一个文件的每一行,为当前密钥添加逗号和值。

答案 1 :(得分:2)

如果输入中存在任意字符,则使用Text::CSV可能最安全。好处是它可以处理引用的分隔符,多行字符串等等。缺点是它可以破坏非csv内容,所以它依赖于你的输入是正确的csv。

use strict;
use warnings;
use Text::CSV;

my $csv = Text::CSV->new({
        binary => 1,
        eol => $/,
    });
my %s;
my ($input, $replace) = @ARGV;
open my $fh, "<", $replace or die "Cannot open $replace: $!";
while (my $row = $csv->getline($fh)) {
    my ($key, $line) = @$row;
    $s{$key} = $line;
}

open $fh, "<", $input or die "Cannot open $input: $!";
while (<$fh>) {
    chomp;
    $csv->print(*STDOUT, [$_, $s{$_}]);
}

答案 2 :(得分:0)

不确定这真的需要一个正则表达式,因为你并没有真正改变你的源代码,就像基于关键字段的'只是'打印一样。

所以我会接近这样的事情:

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

open( my $replace, "<", "replace.txt" ) or die $!;

my %replacements;
while (<$replace>) {
    chomp;
    my ( $key, $value ) = split(/,/);
    $replacements{$key} = $value;
}
close($replace);

open( my $input,  "<", "input.txt" )    or die $!;
open( my $output, ">", "patterns.txt" ) or die $!;

while ( my $line = <$input> ) {
    chomp $line;
    if ( $replacements{$line} ) {
        print {$output} $replacements{$line}, "\n";
    }
}

close($input);
close($output);

它不像其他一些例子那样简洁,但希望更清楚它实际上在做什么。我称之为好事。 (我可以用perl着名的方式使其更加紧凑。