我想在第一次出现时从文件(file.dat)grep一个字符串,并通过从另一个文件(输出)读取来替换它。我有一个名为“output”的文件,例如包含“AAA T 0001”
#!/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
基本上我想要的是:
当第一个实例中的文件“file.dat”中有一个字符串“AAA”时,我想将“AAA”旁边的第二和第三列替换为“T 0001”,但仍保留第一栏“AAA”原样。上面的脚本似乎不起作用。
基本上“$ lin1”和$ srt2变量不在's / $ lin1 / $ srt2 / g'中理解
示例:
在我的file.dat中有一行
AAA D ---- CITY COUNTRY
我想要的是:
AAA T 0001 CITY COUNTRY
非常感谢任何评论。
答案 0 :(得分: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 :(得分:0)
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