我开始利用perl地图的强大功能,遇到了一个我无法找到答案的问题。基本上我正在解析一个unix命令的返回,它有一个我不需要的标题行,然后是每个项目的2行信息。目前,我这样做:
(undef, @ret) = map { [split /\n/] } split(/(?:Host: )/, `cat /proc/scsi/scsi`);
可以跳过标题并为每个“有用”文本行提供一个数组元素。但是,我想构建一个哈希,我知道除了额外的行之外该怎么做。那么我怎样才能在一行代码中忽略第一个数组元素,允许我创建哈希?我正在考虑切片或拼接线的某处,但我需要知道主机上的拆分创建的数组的大小(可能吗?)。我想我也可以做一个(undef,undef,%ret)= map {...}但是如果可以用切片或拼接来完成,那么学习如何做是很好的。
答案 0 :(得分:4)
从split
中移除第一个元素并且仍能够链接更多命令的一种方法是将grep
与状态变量一起使用:
use strict;
use warnings;
my @lines = do {
my $line = 0;
grep {++$line > 1} split /\n/, "1\n2\n3\n4\n5\n6\n7\n"
};
print "@lines";
输出:
2 3 4 5 6 7
但是,我认为你试图在一行代码中做太多。
由于看起来您只是在阅读文件,我建议您使用Perl open
文件,而不是炮轰cat
。
假设您的键/值分隔符是冒号,以下是我建议您构建逻辑的方法:
use strict;
use warnings;
use autodie;
my %hash = do {
open my $fh, '<', '/proc/scsi/scsi';
<$fh>; # Skip Header Row
map {chomp; split /:/, $_, 2} <$fh>
};
答案 1 :(得分:0)
@ret = map { [split /\n/] } (split(/(?:Host: )/, `cat /proc/scsi/scsi`))[1,-1];
让它跳过主机上拆分返回的第一个数组元素。
(以上是完全错误的,正如@ M42指出的那样,仅供参考。)
对于那些感兴趣的人,这是我提出的最终代码(基于@Miller的糟糕方法,有一些简化)来解决我的问题:
my $i;
my $split_RE = qr(\S+|ANSI SCSI revision); # you can create the precise list of keys here
my %attached = map {
chomp;
my ($host, %infohash) = split(/\s*($split_RE):\s*/);
($host => {%infohash} ) # FIXME: one host can have multiple devices.. an array with push() needs to be used here.. somehow (might have to avoid use of map)
}
grep{$i++} # remove/ignore first line
(split(/(?:Host: )/, `cat /proc/scsi/scsi`));
我仍然需要解决主机clobberin&#39;时间,正如@ThisSuitIsBlackNot所指出的那样,但这对我的问题并不紧迫,如果不是微不足道的话应该是直截了当的。