2012-01-24 117 views
5

我有這個Perl代碼只打印第一行而不是所有行。Perl foreach循環僅打印一行

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 

我幾乎可以肯定這是基本的東西。 任何幫助表示讚賞。 謝謝!

+0

不要忘記:'use strict;使用警告;' – Ether

回答

16

的問題是這一行:

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; 
+1

謝謝,TLP。這非常有幫助。我特別感謝額外的信息,因爲我試圖在perl中變得更好。 –

+1

@senile_genius不客氣。 – TLP