2012-06-19 75 views
1

我有一個簡單的問題,我希望你們可以幫忙解釋一下。我正在穩步學習Perl。Perl:將字符串的內容加載到數組中

說我有一個非常大的字符串,例如採取的輸出:

our $z = `du -B MB /home` 

這將產生一個字符串,如下所示:

1MB  /home/debug/Music 
1MB  /home/debug/Downloads 
20MB /home/debug 
20MB /home/ 

我想知道什麼是,我怎麼去加載這個字符串到一個有兩列的數組中,並且n行(其中n是du輸出中的行數)?

我試圖像下面這樣:

my $z1 = `du -B MB /home | tail -4`; 
my @c0 = split (/n/, $z1); 
my $z2 = join (/\t/, @c0); 
my @c2=split(/\t/, $z2); 
print @c2; 

將會產生以下的輸出:

1MB/home/debug/Music1MB/home/debug/Downloads20MB/home/debug20MB/home 

我想我可以使用替代函數s /// g到substitue的目錄空值,並將SPACE值設置爲一個數組,並將空值設爲空值並將其設置爲第二個數組,並將1個數組設置爲另一個數組的鍵。

有沒有人有任何建議,以最好的方式來解決這個問題?

任何幫助表示讚賞。

感謝,

迭戈

+0

,是嗎? – dirkgently

+0

該死的謝謝德克,這就是我從我的外殼歷史複製得到:s – slugman

回答

1
#!/usr/bin/perl; 
my $z= `du -h -d 1 /home/*`; 
my @array = split("\n",$z); 
foreach my $ar(@array) { 
my @ar = split("\t",$ar); 
$ar = \@ar; 
} 

foreach my $entry(@array) { 
print $entry->[0]; 
print $entry->[1]; 

} 
+0

感謝您的非常有用的建議!我想這一點現在 – slugman

+0

嘿用戶,我嘗試了這種代碼,不幸的是我得到了重複幾行以下字符串列表:20MB/home20MB/home20MB/home20MB/home20MB/home20MB/home20MB/home20MB/home20MB/HO e20MB/home20MB/home20MB/home20MB/home20MB/home20MB/home20MB/home20MB/home20MB /小時me20MB/home20MB/home20MB/home20MB/home20MB/home20MB/home20MB/home20MB/home20MB/ome20MB/home20MB/home20MB/home20MB/home20MB/home20MB/home20MB/home20MB/home20MB home20MB/home20MB/home20MB/home20MB/home20MB/home20MB/home20MB/home20MB/home20M/home20MB/home20MB/home20MB/home20MB/home20MB/home20MB/home20MB/home – slugman

+0

其實,我還在使用du -B MB/home 。當我使用你的代碼verbaitm時,它產生了以下輸出:4.0K/home/debug/Public4.0K/home/debug/.hplip4.0K/home/debug/Documents8.0K/home/debug/.ssh320K/home /調試/ .kde208K /家庭/調試/ .electricsheep4.0K /家庭/調試/ Desktop4.0K /家庭/調試/ Pictures4.0K /家庭/調試/ Videos8.0K /家庭/調試/ .mplayer24K /家庭/調試/。 cache224K /家庭/調試/ .thumbnails4.0K /家庭/調試/ Templates12K /家庭/調試/ .emacs.d12K /家庭/調試/ .dbus8.0K /家庭/調試/ .local188K /家庭/調試/ .config4.0K /home/debug/Music4.0K/home/debug/Downloads19M/home/debug4.0K/home/ftp16K/home/lost+found – slugman

1

你或許可以嘗試,並把它們存儲在一個散如下:

#!/usr/bin/perl 

use strict; 
use warnings; 

my $data = '1MB /home/work 4MB /user/bin'; 
my %values = split(' ', $data); 
foreach my $k (keys %values) { 
    print "$k: $values{$k}\n"; 
} 
exit 0; 

注意' 'split第一個參數將匹配任何空格字符(所以我們充分利用它)。對於上面的輸出應該是這樣的:

1MB: /home/work 
4MB: /user/bin 

您必須將原始數據工作納入$data並檢查是否哈希你的作品。

+0

感謝您的非常有用的答案!我現在正在嘗試這個 – slugman

+0

dirk,不幸的是,當我嘗試了這一點後,我收到警告說第7行中存在「奇數個散列分配元素」。爲了不錯誤,我必須在該列表中添加額外的空間。另外,我生成的密鑰如下所示:e:/,/:h,d:e,2:M,B:,1:M,b:u。我認爲我需要更多地修改split語句,然後才能讓它確認元素之間的空間。 – slugman

0

我相信你的perl老兵不會喜歡這個解決方案,但我基本上解決了我的nix根。我之前在for循環中遇到了麻煩,但我意識到我可以利用管道通過shell進行評估,只要答案存儲在一個字符串中即可。

my $z1; my $z2; 

$z1 = `du -B MB /home | cut -f1` 
$z2 = `du -B MB /home | cut -f2` 

my @a1; my @a2; 

@a1 = split("\n", $z1); 
@a2 = split("\n", $z2); 

Array @ a1保存來自第一個字符串的值,@ a2保存來自第二個字符串的值。

我給你們的問題是,是否有一個perl等同於unix'cut'工具?即我可以在哪裏將字符串輸出分割爲第一個製表符分隔的字段?這是我必須探索的一個問題。

Diego Diego

0

我真的不知道你在做什麼。如果你只是想有n個元素,每個裏面有一兩米欄的字符串數組,你需要看起來距離不超過

my @z1 = `du -B MB /home | tail -4`; 

例如,文件的第三行可以訪問(記住perl的陣列爲基礎的0):

print $z1[2]; 

產生輸出

20MB /home/debug 

更多有用。將捕獲每個目錄的大小在哈希:

my %dir2size; 
foreach (@z1) { 
    my @line = split /\s+/; 
    $dir2size{$line[1]} = $line[0]; 
} 
foreach my $key (sort keys %dir2size) { 
    print "$key: $dir2size{$key}\n"; 
} 

產生第一`split`應該使用`z1`作爲第二個參數的輸出

/home/: 20MB 
/home/debug: 20MB 
/home/debug/Downloads: 1MB 
/home/debug/Music: 1MB