2013-03-09 58 views
0

我想在第一次出现时从文件(file.dat)中grep一个字符串,并通过从另一个文件(输出)读取来替换它。我有一个名为“输出”为例,文件中包含“AAA牛逼0001”如何通过grep和perl替换字符串

#!/bin/bash 
procdir=`pwd` 

cat output | while read lin1 lin2 lin3 

do 

    srt2=$(echo $lin1 $lin2 $lin3 | awk '{print $1,$2,$3}') 

    grep -m 1 $lin1 $procdir/file.dat | xargs -r0 perl -pi -e 's/$lin1/$srt2/g' 

done 

基本上我想要的是:

当过一个字符串“AAA”从文件grep'ed“文件.dat“,我想用”T 0001“替换”AAA“旁边的第二列和第三列,但仍保留第一列”AAA“。上面的脚本似乎不起作用。

基本上 “$林1” 和$ SRT2变量不是 'S/$林1/$ SRT2/G' 内了解

例:

我FILE.DAT

我有一排

AAA D ---- CITY COUNTRY 

我要的是:

AAA T 0001 CITY COUNTRY 

任何意见都非常赞赏。

+1

什么?请在'file.dat'和'output'中显示数据以及你想要的结果。 – Borodin 2013-03-09 19:44:16

+1

[grep和replace]的可能重复(http://stackoverflow.com/questions/15234334/grep-and-replace) – ikegami 2013-03-09 20:03:21

回答

1

Perl在这类任务中发光。

下面的代码从output中读取替换,并记住随每个键的第一个出现一起出现的新字段。使用Perl就地编辑,程序然后逐行读取输入。必要时,代码将替换字段2和3,并从%replace中删除密钥,以便仅替换第一个实例。

#! /usr/bin/env perl 

use strict; 
use warnings; 

die "Usage: $0 replacements data-file\n" unless @ARGV == 2; 

sub read_replacements { 
    my($path) = @_; 

    my %replace; 
    open my $fh, "<", $path or die "$0: open $path: $!"; 
    while (<$fh>) { 
    chomp; 
    my($key,$f2,$f3) = split; 
    warn "$0: $path:$.: multiple replacements for key '$key'" if $replace{$key}; 
    $replace{$key} = [$f2,$f3]; 
    } 

    %replace; 
} 

my %replace = read_replacements shift @ARGV; 
$^I = "~"; # in-place editing backup extension 
while (<>) { 
    chomp; 
    my($key,@rest) = split; 
    if ($replace{$key}) { 
    splice @rest, 0, 2 => @{$replace{$key}}; 
    $_ = join(" ", $key, @rest) . $/; 
    delete $replace{$key}; 
    } 
    print; 
} 

采样运行:

$ cat output 
AAA T 0001 

$ cat file.dat 
AAA D ---- CITY COUNTRY 

$ ./replace-first output file.dat 

$ cat file.dat 
AAA T 0001 CITY COUNTRY 

$ cat file.dat~ 
AAA D ---- CITY COUNTRY

就地编辑是一个很好的功能,你可以很容易地扩展上面的程序替换文件的任意数量的字段。

-1
perl -i -e' 
    { 
     my $f = shift(@ARGV); 
     open(my $fh, "<", $f) 
     or die("Can'\''t open $f: $!\n"); 
     while (<$fh>) { 
     my ($s,$r) = /^(\S+)\s++(.*)$/; 
     $repl{$s} = $r; 
     } 
    } 

    while (<>) { 
     s{^(\S+)\s+\K(\S+\s*\S+)}{ delete($repl{$1}) // $2 }e; 
     print; 
    } 
' output file.dat