Regular-Expression
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
我試圖編寫一段程式碼來做到這一點,但它不起作用,因為它似乎添加了 a
0
以及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"; } }
在 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