Perlパターンのマッチングと置換は4番目の単語だけを置き換え、残りはすべて保持します。

Perlパターンのマッチングと置換は4番目の単語だけを置き換え、残りはすべて保持します。

各行の4番目の単語を次のように置き換える必要があります0

オリジナル:

R5_427 MMP15@2:S VDD:1 967.796 TC1=0.0004785156
R5_428 MMP15@2:S lninst_M55:S 0.001

予想出力:

R5_427 MMP15@2:S VDD:1 0 TC1=0.0004785156
R5_428 MMP15@2:S lninst_M55:S 0

このためにコードを書いてみましたが、最初のテストケースに0aを追加するのと同じようには機能しません967.796。 3番目の単語の後の正確な単語数に依存しない一般的な解決策を探しています。

私の試み:

while(<RD>)
{
    my $line;
    $line = $_;
    chop $line; 
    if ($line =~ /^R(\S+)\s+(\S+)\s+(\S+)\s+(.*$)/) {
        my $mod_line = "R$1 $2 $3 0 $4";
        print WR "$mod_line\n";
    }
    else {
        print WR "$line\n";
    }
}

ベストアンサー1

Perlでは、次のようにすることができます。

 #!/usr/bin/env perl

while (<>) {
  ## split the line into fileds on whitespace
  my @fields = split(/\s+/);
  ## set the 4th field (numbering starts at 0) to "0" if
  ## this line starts with an R (since that's what you had originally)
  $fields[3] = 0 if /^R/;
  ## join thew fields with a space and print
  print join(" ", @fields) . "\n";
}

例で上記のコマンドを実行すると、次の結果が表示されます。

$ foo.pl file 
R5_427 MMP15@2:S VDD:1 0 TC1=0.0004785156
R5_428 MMP15@2:S lninst_M55:S 0

または、より複雑な正規表現を使用して元のロジックを保存するには、次のようにします。

#!/usr/bin/env perl
open(my $RD, '<', $ARGV[0]);
while(<$RD>)
{
  ## you want chomp, not chop. chomp only removes trailing newlines
  ## while chop removes the last character no matter what it is.
  ## You also don't need the $line variable, perl will default to $_
  chomp;
  ## You don't need to capture every group, only the
  ## ones you will use later. Also, to allow for only
  ## three fields, you need '\s*.*' and not '\s+.*'
  if (/^(R\S+\s+\S+\s+\S+)\s+\S+(\s*.*)/) {
    ## No need for a temp variable, just print
    print "$1 0 $2\n";
  }
  else {
    print "$_\n";
  }
}

もちろん、このためにスクリプトを書く必要はなく、次の1行を書くだけです。

$ perl -lane '$F[3] = 0 if /^R/; print join(" ", @F)' file 
R5_427 MMP15@2:S VDD:1 0 TC1=0.0004785156
R5_428 MMP15@2:S lninst_M55:S 0

おすすめ記事