0

我只想在第一次出现时从文件(file.dat)中获取一个字符串,并通过从另一个文件(输出)中读取来替换它。我有一个名为“输出”的文件,例如包含“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”就这样。上面的脚本似乎不起作用。

基本上在 's/$lin1/$srt2/g' 中不理解 "$lin1" 和 $srt2 变量

例子:

在我的 file.dat 我有一排

AAA D ---- CITY COUNTRY

我想要的是:

AAA T 0001 CITY COUNTRY

任何意见都非常感谢。

4

2 回答 2

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;
}

样品运行:

$猫输出
AAA T 0001

$猫文件.dat
AAA D----城市国家

$ ./replace-first 输出文件.dat

$猫文件.dat
AAA T 0001 城市 国家

$ cat file.dat~
AAA D----城市国家

就地编辑是一个不错的功能,您可以轻松扩展上述程序以替换任意数量文件中的字段。

于 2013-03-09T20:05:13.140 回答
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
于 2013-03-09T20:13:22.903 回答