你最大的問題是你編輯$_
,所以第二次通過循環,字符串中不再有「Ix」和「Ay」。
$loop=0;
while ($loop < $max) {
my $local = $max-$loop;
my $line = $_;
$line =~ s/Ix/I$loop/;
$line =~ s/Ay/A$local/;
print "$line\n";
$loop++;
}
你也可以考慮使用for
循環:
for my $loop (0 .. ($max - 1)) {
my $local = ($max - $loop);
my $line = $_;
$line =~ s/Ix/I$loop/;
$line =~ s/Ay/A$local/;
print "$line\n";
}
如果這些是空間分隔的「列」,你想只有在「列」編輯值2和3(您在awk
的$2
提及似乎暗示),您可以拆分輸入,以及是否:split
命令故意模仿awk
從perldoc -f split
:
As another special case, "split" emulates the default behavior of
the command line tool awk when the PATTERN is either omitted or a
literal string composed of a single space character (such as ' '
or "\x20", but not e.g. "/ /"). In this case, any leading
whitespace in EXPR is removed before splitting occurs, and the
PATTERN is instead treated as if it were "/\s+/"; in particular,
this means that any contiguous whitespace (not just a single space
character) is used as a separator. However, this special treatment
can be avoided by specifying the pattern "/ /" instead of the
string " ", thereby allowing only a single space character to be a
separator.
If omitted, PATTERN defaults to a single space, " ", triggering
the previously described awk emulation.
這給我們帶來:
local $" = ' '; #" (syntax highlighting bug on SO)
my @input = split;
if ($input[1] =~ /Ix/) {
for my $loop (0 .. ($max - 1)) {
my $local = ($max - $loop);
my @line = @input;
$line[1] =~ s/Ix/I$loop/;
$line[2] =~ s/Ay/A$local/;
print "@line\n";
}
} else {
print "$_\n";
}
特殊變量$"
具體是指"@line"
將在印有該陣列的每個元素之間的' '
,讓您得到您的「列」回輸出。
最後一個暗示:你die
可以僅通過包括$!
打印有意義的錯誤消息:
#!/usr/bin/perl -w
use strict;
my $loop=0;
my $max=3;
my $in_file="$ARGV[0]";
local $" = ' '; #" (syntax highlighting bug on SO)
open (PH, "$in_file") or die "check file: $!";
while (<PH>) {
chomp;
my @input = split;
if ($input[1] =~ /Ix/) {
for my $loop (0 .. ($max - 1)) {
my $local = ($max - $loop);
my @line = @input;
$line[1] =~ s/Ix/I$loop/;
$line[2] =~ s/Ay/A$local/;
print "@line\n";
}
} else {
print "$_\n";
}
}
close(PH);
編輯:
由於@Kenosis在評論中指出,你所提供的樣本輸出有I
計數器運行1 ... 3而不是0 ... 2。在你的循環中,你將計數器初始化爲0,並且只在打印後才遞增,所以我將(錯誤)解釋爲你的意圖。
幸運的是,改變這個很簡單:
for my $loop (1 .. $max) {
my $local = (1+ $max - $loop);
…
由於還指出,使用的詞彙(my
)變量的文件句柄是通常更安全/更好地爲各種技術原因,以及;
open my $ph, '<', $infile or die "Can't read $infile: $!";
…
while (<$ph>) {
…
...儘管您使用的舊式文件句柄(裸詞標識符)仍然有效。 這也顯示了「3參數open
」,它在「2-arg」形式中防止了一些可能的安全漏洞(或奇怪的,令人撓頭的瘋狂行爲),<
預設爲文件名。
而且,作爲@Kenosis筆記,$"
確實發生默認爲' '
,但我傾向於重新定義「以防萬一」(我個人有一個Perl代碼很多重新定義它象外之象','
或"\t"
由於種種原因,你可以local
LY重置,以確保您的輸出將是什麼樣子)
有很多方法可以編寫這段代碼。請給我們一個真實的用例。 – bluefeet
是與所示完全相同的文字輸入? 「Ix」,「Ay」?是否有任何y和x被替換,或者只有第二個字段中的I和第三個字段中的y(或多個y?)之後的x? – ysth