0

ファイル(file.dat)からのみ最初に出現した文字列をgrepし、別のファイル(出力)から読み取ることで置き換えたいと思いました。例として「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

基本的に私が欲しかったのは:

最初のインスタンスで文字列「AAA」がファイル「file.dat」から grep されるたびに、「AAA」の隣の 2 番目と 3 番目の列を「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のインプレース編集を使用して、プログラムは入力を1行ずつ読み取ります。必要に応じて、コードはフィールド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

$ 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

インプレース編集は優れた機能であり、上記のプログラムを簡単に拡張して、任意の数のファイルのフィールドを置き換えることができます。

于 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 に答える