Perl替换中的Grep(RHS)

时间:2015-03-03 13:40:37

标签: perl grep substitution

我想基于"字符串字符串"替换文本。文件$ key中定义的对。

示例输入文件 $ input

a b c foo
d e f moo
g h i boo

Predefined" Key"档案 $ key

cow moo
code foo
ghost boo
cheer woo

期望输出

a b c code
d e f cow
g h i ghost

我的尝试

perl -pe 's/(.*?)(\woo)/$1qq{grep -oP ".*(?=\s$2)" $key}/e' $input > $output

错误返回

syntax error at -e line 1, near "$1qq{grep -oP ".*(?=\s$2)" $key}"
syntax error at -e line 1, near "s/(.*?)(\woo)/$1qq{grep -oP ".*(?=\s$2)" $key}/ee"

任何帮助都将不胜感激。

非常欢迎有关更好地实现所需结果的建议,但理想情况下, / p>

4 个答案:

答案 0 :(得分:4)

从命令行使用perl,

perl -lane'
  BEGIN{ local @ARGV = pop; %h = reverse map split, <> }
  print join " ", @F[0..2], $h{$F[3]};

' input key

输出

a b c code
d e f cow
g h i ghost

更新

perl -lane'
  BEGIN{ local @ARGV = pop; %h = reverse map /(.+)\s+(\S+)$/, <> }
  print join " ", @F[0..2], $h{$F[3]};

' input key

答案 1 :(得分:3)

以下是使用awk

的方法
awk 'FNR==NR {a[$2]=$1;next} $NF=a[$NF]' key input
a b c code
d e f cow
g h i ghost

它将key文件读取到数组a
然后使用数组input的键打印a文件以更改最后一个字段。

如果a[$NF]可能是0,请使用:

awk 'FNR==NR {a[$2]=$1;next} {$NF=a[$NF];print}' key input

答案 2 :(得分:3)

$1qq{grep -oP ".*(?=\s$2)" $key}

不是有效的Perl表达式。也许你的意思是

$1 . qq{grep -oP ".*(?=\s$2)" $key}

尽管该表达式中还有许多其他错误。 (您使用qq{},您应该使用qx{},忘记逃避\,使用$key而没有为其分配值,可能更多。)< / p>

只能读取密钥文件一次的可维护解决方案:

perl -e'
   my %lookup;
   open(my $fh, "<", shift(@ARGV))
      or die $!;

   while (<$fh>) {
      my ($v,$k) = split;
      $lookup{$k} = $v;
   }

   while (<>) {
      my @f = split;

      next if !@f;  # Skip blank lines.

      if (defined($lookup{$f[3]})) {
         warn("Can'\''t find key \"$f[3]\". Copying record unchanged.\n");
         print;
         next;
      }

      $f[3] = $lookup{$f[3]};
      print("@f\n");
   }
' keyfile.txt input.txt >output.txt

答案 3 :(得分:2)

个人 - 我不喜欢做一个衬垫,因为它们很难读。

模式替换的一般技巧是:

my %replacements;
open ( my $keyfile, "<", "key_file.txt" ) or die $!;
while ( $keyfile ) {
     chomp;
     my ( $value, $key ) = split;
     $replacements{$key} = $value; 
}

my $regex = join ( "\b|\b", keys %replacements ); 
$regex = qr/$regex/; 

open ( my $replace_fh, "<", "input_file" ) or die $!; 
while ( <$replace_fh> ) {
    s/\b($regex)\b/$replacements{$1}/g;
    print;
}

将您的输入转换为替换的哈希值,构造匹配其中任何单词的正则表达式,然后使用该正则表达式“匹配” - 使用$1哈希的查找键。