Perl:从系统输出中分离变量(df -lh)

时间:2016-05-19 09:45:51

标签: perl mount-point

我设法使用反向标记将我的df -lh命令存储为变量$var,但我想将其拆分,以便变量的每个部分都可以分配给另一个变量。

打印$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

我想要删除第一行标题,然后将其拆分为以下类别:

$filesystem$size$used$avail$cap$mounted

我尝试使用shift来摆脱第一行,但我现在知道这只适用于数组。对于我拥有的不同阵列,我使用chomp,即

foreach my $line (@output) {
              chomp $line;
              my( $filesystem, $size, $used, $avail, $cap, $mounted ) = split (/\s+/, $line);
}

但由于这不是一个阵列,我不知道如何去做,除非有办法将我的系统输出存储为数组?

非常感谢。

3 个答案:

答案 0 :(得分:3)

是的,shift适用于数组。但是列表上下文中的反引号将返回命令输出的行列表。您可以将该列表分配给一个数组,然后shift标题行从开头

以下是您可能编写的内容的示例,以及我在VBox系统上运行时的输出。我对字段的所有操作都是打印它们的值,因为你没有提到你可能想要用它们做什么

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 )

答案 1 :(得分:1)

使用哈希切片方法怎么样?

#!/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

我们指定要拆分的计数,因为看起来就像它只是包含空格的最后一个字段一样。 (否则你会有另一个列'打开','Install OS X Yosemite'也会被拆分。

这构建了一个这样的数据结构:

$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'
          }
        ];

这是一个哈希数组。 (例如,每个值都是'键入')。

但是你可以做一些类似的事情,只需将值split改为数组。

答案 2 :(得分:0)

我完成的代码:

 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没有摆脱容量的百分比,所以摆脱它,以便将它添加到我的数据库中。存储为数组。感谢大家的帮助和评论!