各行の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
このためにコードを書いてみましたが、最初のテストケースに0
aを追加するのと同じようには機能しません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
答え2
1つの方法は、最初の3つのフィールドをスキップし、抵抗に対してのみ4番目のフィールドを0.0に置き換えることです。
$ perl -pe 's/^R(?:\S+\s+){3}\K\S+/0.0/' file
R5_427 MMP15@2:S VDD:1 0.0 TC1=0.0004785156
R5_428 MMP15@2:S lninst_M55:S 0.0