【问题标题】:Perl foreach loop prints only one linePerl foreach 循环只打印一行
【发布时间】:2012-01-24 20:59:37
【问题描述】:

我有这个 Perl 代码,它只打印第一行而不是所有行。

use Net::SSH::Perl;
my $user = "user"; 
my $cmd = "df -m | grep data";
my $host = "host1.example.com"; 

my $ssh = Net::SSH::Perl->new($host);
$ssh->login($user);
my ($dflines,$errors,$exit) = $ssh->cmd($cmd);
foreach $line ($dflines) {
  print "$line";
  my @values = split(' ',$line);
  my ($MBsize, $MBused, $MBavail, $dir) =
      ($values[1], $values[2], $values[3], $values[5]);
  print "MBsize=$MBsize MBused=$MBused MBavail=$MBavail dir=$dir\n";
}

打印出来:

/dev/sdb1              1407118    931813    403828  70% /data1
/dev/sdc1              1407118    921739    413902  70% /data2
/dev/sdd1              1407118    909408    426233  69% /data3
/dev/sde1              1407118    918828    416813  69% /data4
/dev/sdf1              1407118    922335    413306  70% /data5
MBsize=1407118 MBused=931813 MBavail=403828 dir=/data1

我希望:

/dev/sdb1              1407118    931813    403828  70% /data1
/dev/sdc1              1407118    921739    413902  70% /data2
/dev/sdd1              1407118    909408    426233  69% /data3
/dev/sde1              1407118    918828    416813  69% /data4
/dev/sdf1              1407118    922335    413306  70% /data5
MBsize=1407118 MBused=931813 MBavail=403828 dir=/data1
MBsize=1407118 MBused=921739 MBavail=413902 dir=/data2
MBsize=1407118 MBused=909408 MBavail=426233 dir=/data3
MBsize=1407118 MBused=918828 MBavail=416813 dir=/data4
MBsize=1407118 MBused=922335 MBavail=413306 dir=/data5

我几乎可以肯定这是基本的东西。 任何帮助表示赞赏。 谢谢!

【问题讨论】:

  • 别忘了:use strict; use warnings;

标签: perl foreach


【解决方案1】:

问题出在这一行:

foreach $line ($dflines) {

您只执行一次迭代,因为那不是一个数组,而是一个标量。当您 print "$line" 它实际上打印了您捕获的所有行,但我猜您看起来像是在一个循环中打印了许多值。在后续部分:

my @values = split(' ',$line);
my ($MBsize, $MBused, $MBavail, $dir) = 
        ($values[1], $values[2], $values[3], $values[5]);
print "MBsize=$MBsize MBused=$MBused MBavail=$MBavail dir=$dir\n";

您只使用拆分的前几个值,但该行的其余部分也在那里。换句话说,@values 包含您期望的所有值。范围 0..5 包含第一行,6..10 包含下一行,依此类推。由于您只使用前 6 个值,因此您看不到它们。

一个快速的解决方法可能是:

foreach $line (split /\n/, $dflines) {

这会以您期望的方式分解您的输入。

一些提示:

总是use warnings; use strict;

你应该使用一些适当的 perl 特性:

for my $line (split /\n/, $dflines) {
   print $line;
   my @values = split ' ', $line;
   printf "MBsize=%s MBused=%s MBavail=%s dir=%s\n", @values[1,2,3,5];
}

您似乎想在常规输出之后打印MBsize ... 行。如果是这样,您可以将这些行存储在一个数组中并在循环后打印:

my @print;
for my $line (split /\n/, $dflines) {
   print $line;
   my @values = split ' ', $line;
   push @print, sprintf "MBsize=%s MBused=%s MBavail=%s dir=%s\n", @values[1,2,3,5];
}   # note  ----^ sprintf instead
print @print;

【讨论】:

  • 谢谢,TLP。那非常有帮助。当我试图在 perl 上做得更好时,我特别感谢这些额外的信息。
猜你喜欢
  • 1970-01-01
  • 2021-05-21
  • 1970-01-01
  • 1970-01-01
  • 2013-11-28
  • 1970-01-01
  • 1970-01-01
  • 2017-09-17
  • 1970-01-01
相关资源
最近更新 更多