2012-06-19 46 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