Reputation: 79
I've managed to use back-ticks to store my df -lh
command as a variable, $var
, but I would like to split it up so that each part of the variable can be assigned to another variable.
Here is my output when I print $var
:
Filesystem Size Used Avail Capacity iused ifree %iused Mounted on
/dev/disk0s2 931Gi 82Gi 849Gi 9% 21503280 222477462 9% /
/dev/disk1s2 19Gi 5.0Gi 14Gi 27% 1303373 3579438 27% /Volumes/Install OS X Yosemite
/dev/disk1s3 1.8Ti 174Gi 1.6Ti 10% 45714072 437656799 9% /Volumes/store
What I would like is to remove the first line of headers, then split it down into the following categories of:
$filesystem
, $size
, $used
, $avail
, $cap
, $mounted
.
I've tried using shift to get rid of the first line, but I am aware now that this is only for arrays. For a different array I have, I use chomp, i.e.
foreach my $line (@output) {
chomp $line;
my( $filesystem, $size, $used, $avail, $cap, $mounted ) = split (/\s+/, $line);
}
But as this is not an array, I don't know how to go about it, unless there is a way to store my system output as an array?
Many thanks.
Upvotes: 0
Views: 568
Reputation: 126722
Yes, shift
does work on arrays. But backticks in list context will return a list of lines output by the command. You can assign that list to an array and then shift
the header line off the beginning
Here's an example of what you might write, and the output when I run it on my VBox system. All I do with the fields is print their values as you haven't mentioned what you might want to do with them
use strict;
use warnings 'all';
use feature 'say';
my @df = `df -l`;
shift @df;
chomp @df;
for ( @df ) {
my ( $filesystem, $size, $used, $avail, $cap, $mounted ) = split ' ', $_, 6;
say "( $filesystem, $size, $used, $avail, $cap, $mounted )";
}
( udev, 1004960, 0, 1004960, 0%, /dev )
( tmpfs, 204852, 6264, 198588, 4%, /run )
( /dev/sda1, 49409840, 4925512, 41951416, 11%, / )
( tmpfs, 1024260, 132, 1024128, 1%, /dev/shm )
( tmpfs, 5120, 4, 5116, 1%, /run/lock )
( tmpfs, 1024260, 0, 1024260, 0%, /sys/fs/cgroup )
( tmpfs, 204852, 52, 204800, 1%, /run/user/1000 )
( /dev/sr0, 56782, 56782, 0, 100%, /media/rob/VBOXADDITIONS_5.0.18_106667 )
Upvotes: 3
Reputation: 79
My finished code:
my @var= `df -l`;
my $local_id = 2;
shift @var; ## REMOVE TOP LINE
foreach my $line (@var) {
chomp $line;
my( $filesystem, $size, $used, $avail, $cap, $mounted ) = split (/\s+/, $line);
## DIRTY QUICK WAY TO PULL OFF %
$cap = substr($cap, 0, -1);
}
Df -l does not get rid of the % of capacity, so got rid of that in order to add it into my db. Stored as an array. Thanks everyone for your help and comments!
Upvotes: 0
Reputation: 53478
How about using a hash slice approach?
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
chomp ( my @header = split ' ', <DATA>, 9 );
my @rows;
while ( <DATA> ) {
chomp;
my %this_row;
push @rows, \%this_row;
@this_row{@header} = split ' ', $_, 9;
print Dumper \%this_row;
}
print Dumper \@rows;
foreach my $row ( @rows ) {
print $row -> {Filesystem}, " => ", $row -> {Size},"\n";
}
__DATA__
Filesystem Size Used Avail Capacity iused ifree %iused Mounted on
/dev/disk0s2 931Gi 82Gi 849Gi 9% 21503280 222477462 9% /
/dev/disk1s2 19Gi 5.0Gi 14Gi 27% 1303373 3579438 27% /Volumes/Install OS X Yosemite
/dev/disk1s3 1.8Ti 174Gi 1.6Ti 10% 45714072 437656799 9% /Volumes/store
We specify a count to split, because it looks like it's only your last field that contains spaces. (Otherwise you'd have another column 'on' and that 'Install OS X Yosemite'
would get split too).
This builds a data structure like this:
$VAR1 = [
{
'Filesystem' => '/dev/disk0s2',
'Mounted on' => '/',
'Avail' => '849Gi',
'%iused' => '9%',
'Size' => '931Gi',
'iused' => '21503280',
'Capacity' => '9%',
'Used' => '82Gi',
'ifree' => '222477462'
},
{
'Capacity' => '27%',
'iused' => '1303373',
'Size' => '19Gi',
'%iused' => '27%',
'Filesystem' => '/dev/disk1s2',
'Mounted on' => '/Volumes/Install OS X Yosemite',
'Avail' => '14Gi',
'ifree' => '3579438',
'Used' => '5.0Gi'
},
{
'ifree' => '437656799',
'Used' => '174Gi',
'Capacity' => '10%',
'iused' => '45714072',
'%iused' => '9%',
'Size' => '1.8Ti',
'Avail' => '1.6Ti',
'Mounted on' => '/Volumes/store',
'Filesystem' => '/dev/disk1s3'
}
];
Which is an array of hashes. (e.g. each value is 'keyed').
But you could do something similar where you just split
the values into an array instead.
Upvotes: 1