![Perl 패턴 일치 및 교체는 네 번째 단어만 바꾸고 나머지는 모두 유지합니다.](https://linux55.com/image/182699/Perl%20%ED%8C%A8%ED%84%B4%20%EC%9D%BC%EC%B9%98%20%EB%B0%8F%20%EA%B5%90%EC%B2%B4%EB%8A%94%20%EB%84%A4%20%EB%B2%88%EC%A7%B8%20%EB%8B%A8%EC%96%B4%EB%A7%8C%20%EB%B0%94%EA%BE%B8%EA%B3%A0%20%EB%82%98%EB%A8%B8%EC%A7%80%EB%8A%94%20%EB%AA%A8%EB%91%90%20%EC%9C%A0%EC%A7%80%ED%95%A9%EB%8B%88%EB%8B%A4..png)
각 줄의 네 번째 단어를 다음으로 바꿔야 합니다 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개 필드를 건너뛰고 저항에 대해서만 네 번째 필드를 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