我需要将每一行的第四个单词替换为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
。我正在寻找一个通用的解决方案,不依赖于第三个单词之后的确切单词数。
我的尝试:
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";
}
}
当然,你并不需要为此编写脚本,你可以只写一行:
$ 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
一种方法是跳过前 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