Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

perl discard first array element in map operation

I'm starting to harness the power of perl map, and have run into a question that I couldn't find an answer to. Basically I am parsing the return of a unix command which has a header line that I don't need, and then 2 lines of information per item. Currently, I am doing this:

(undef, @ret) = map { [split /\n/] } split(/(?:Host: )/, `cat /proc/scsi/scsi`);

Which works fine to skip the header and give me one array element per "useful" line of text. However, I want to build a hash instead, which I would know how to do except for that extra line. So how can I, in a single line of code, ignore that first array element, to allow me to create the hash? I was thinking somewhere along the lines of a slice or a splice, but I would need to know the size of the array created by the split on Host (is that possible?). I guess I could also do a (undef,undef, %ret) = map {...} but if this could be done with a slice or a splice, that would be great to learn how.

like image 334
insaner Avatar asked Apr 25 '26 23:04

insaner


1 Answers

One way to remove the first element from a split and still be able to chain a more commands would be to use grep with a state variable:

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";

Output:

2 3 4 5 6 7

However, I think you're trying to do too much in a single line of code.

Since it appears you're just reading a file, I would suggest that you use Perl to open the file instead of shelling out to cat.

Assuming your key / value delimiter is a colon, the following is how I'd recommend you construct your logic:

use strict;
use warnings;
use autodie;

my %hash = do {
    open my $fh, '<', '/proc/scsi/scsi';
    <$fh>; # Skip Header Row
    map {chomp; split /:/, $_, 2} <$fh>
};
like image 176
Miller Avatar answered Apr 28 '26 12:04

Miller