我有一个名为numbers.txt的文件,它基本上与5个数字对齐: 它们看起来像这样:
1 2 3 4 5
我想要实现的是我想从行中读取这些数字(已经有效),然后在每次迭代中我想为从该文件读取的每个数字添加+1并在屏幕上打印它们有了打印,所以最终的结果应该是这样的:
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
5 6 7 8 9
#!/usr/bin/perl
use strict;
use warnings;
open("handle", 'numbers.txt') or die('unable to open numbers file\n');
$/ = ' ';
OUT: for my $line (<handle>) {
for (my $a = 0; $a < 5; $a++) {
chomp $line;
$line += 1;
print "$line ";
next OUT;
}
}
close("handle");
暂时没有在perl中完成循环,如果有人可以提供工作示例,那就太棒了。
另外,如果您能提供多个工作示例,那将是非常好的,只是为了将来证明;) 感谢
答案 0 :(得分:1)
您可以尝试使用此尺寸。
#!/usr/bin/perl
use strict;
use warnings;
open("handle", 'numbers.txt') or die('unable to open numbers file\n');
for my $line (<handle>) {
chomp $line;
for my $number (split /\s+/, $line) {
for (my $a = $number; $a < $number+5; $a++) {
print "$a ";
}
print "\n";
}
}
close("handle");
您可以省去 $ / =&#39; &#39; 而是让外循环迭代文件的行。
对于每个要用空格分隔的数字进行迭代的每一行,因此 split / \ s + /,$ line 会为您提供内部循环的数字列表。
对于您的输出$ a从文件读取的数字开始。
答案 1 :(得分:1)
这将完成您的工作:
use strict;
use warnings;
while(<DATA>) {
chomp;
print "$_\n";
my @split = split;
my $count = 0;
for (1..4){
$count++;
foreach (@split){
my $num = $_ + $count;
print "$num ";
}
print "\n";
}
}
__DATA__
1 2 3 4 5
答案 2 :(得分:1)
更新添加了另一种方法,这个方法与发布的方法一致。
增加字符串中的每个数字,更改字符串。重复一遍。以下是两种方法。另一种方法是读取单个数字并按照整数序列打印。
(1)使用正则表达式。它也适合单线
echo "1 2 3 4 5" | perl -e '$v = <>; for (1..5) { print $v; $v =~ s/(\d+)/$1+1/eg; }'
这将打印所需的输出。但最好把它放在脚本中
use warnings;
use strict;
my $file = 'numbers.txt';
open my $fh, '<', $file or die "can't open $file: $!";
while (my $line = <$fh>) {
# Add chomp($line) if needed for some other processing.
for (1..5) {
print $line;
$line =~ s/(\d+)/$1+1/eg;
}
}
/e
修饰符对此至关重要。它使得正则表达式的替换方被评估为代码而不是双引号字符串。所以你实际上可以在那里执行代码,在这里我们为每个匹配的数字添加捕获的数字$1+1
,因为/g
向下移动字符串。这会更改字符串,以便for (1..5)
的下一次迭代递增那些,等等。我匹配多个数字\d+
,这在您的示例中不是必需的,但通常会更有意义。
(2)通过split
+ map
+ join
,也反复更改线路
while (my $line = <$fh>) {
for (1..5) {
print $line;
$line = join ' ', map { $_+1 } split '\s+', $line;
}
}
split
获取$line
中的数字列表并将其提供给map
,join
将每个数字递增,将其输出列表提供给$line
。已连接的字符串将分配回\s+
,并重复此操作。我按' '
分割以允许多个空格,但这使得它接受的输入格式非常“放松”,请参阅perlrecharclass
。如果您知道它是一个空格,请将其更改为open my $fh, '<', $file or die "can't open $file: $!";
local $/ = ' ';
while (my $num = <$fh>) {
print "$_ " for $num..$num+4;
print "\n";
}
。
(3)一次取一个数字并从中打印整数序列。
4
可以通过预处理整行来编码神奇的my $len = () = $line =~ /(\d+)/g;
以查找序列长度,例如
split
或scalar
- 进入数组并获取$len-1
,然后使用open my $fh, '<', $file
。
补充评论。
我建议使用三参数open die "Your message: $!"
检查通话时,请打印错误if ($bad) { die "Got $bad" }
,以查看失败的原因。如果您决定退出$!
,那么您可能不需要$!
。但是当外部呼叫失败时,您不知道原因,因此您需要合适的错误变量,通常是{{1}}。
答案 3 :(得分:1)
这里不需要使用嵌套循环它总是使程序变慢。
#!/usr/bin/perl
use strict;
use warnings;
my @num = split(" ",(<DATA>)[0]);
foreach my $inc (0..$#num)
{
print map{$inc+$_," "}@num; # Add one by one in array element
print "\n";
}
__DATA__
1 2 3 4 5
答案 4 :(得分:0)
您的计划存在许多问题。这是阻止它工作的原因
您正在将记录分隔符设置为单个空格。您的输入文件包含"1 2 3 4 5\n"
,因此while
循环将重复五次,将$line
设置为"1 "
,"2 "
,"3 "
,{{1 },"4 "
您的"5\n"
循环设置为迭代五次。它会for
删除数字后的空格,然后递增chomp $line
并打印它。然后你跳出$line
循环,只用for
执行一次。这会导致文件中的每个值加1并打印,因此您得到next OUT
删除不必要的2 3 4 5 6
,产生更接近的东西
next OUT
现在输入文件中的每个数字都会打印五个数字
在2 3 4 5 6 3 4 5 6 7 4 5 6 7 8 5 6 7 8 9 6 7 8 9 10
循环后添加print "\n"
帮助分隔行
for
现在我们需要在之前打印数字,而不是之后。如果我们交换2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
5 6 7 8 9
6 7 8 9 10
和$line += 1
,我们就会得到这个
print "$line "
这里发生的是1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
5
6 7 8 9
仍然是一个换行符,现在出现在输出中。 5
不会删除此内容,因为它会从字符串末尾删除chomp
的值。您已将其设置为空格,因此它将仅删除空格。修复方法是用替换$/
替换chomp
,替换*字符串中的所有空格。你还需要这样做一次,所以我把它放在顶部的s/\s+//g
循环之外
现在我们得到这个
for
这是你的代码,因为它结束了
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
5 6 7 8 9
还有一些其他最佳做法可以改善您的计划
使用use strict;
use warnings;
open( "handle", 'numbers.txt' ) or die('unable to open numbers file\n');
$/ = ' ';
for my $line (<handle>) {
$line =~ s/\s+//g;
for ( my $a = 0; $a < 5; $a++ ) {
print "$line ";
$line += 1;
}
print "\n";
}
close("handle");
使用词法文件句柄和use warnings 'all'
如果要更改Perl的内置变量,请使用open
将local
放入您的$!
字符串中,以便您知道为什么 die
失败
避免使用C风格的open
循环,而是迭代列表
这些修复也是这样的。输出与上面的
相同for