正则表达式帮助unix df

jda*_*mae 2 perl

我需要一些帮助调整我的代码来查找此unix df输出中的另一个属性:

防爆.

Filesystem     Size    Used   Avail Capacity  Mounted on
/dev/ad4s1e     61G     46G    9.7G    83%    /home
Run Code Online (Sandbox Code Playgroud)

到目前为止,我可以提取容量,但现在我想添加Avail.

这是我的perl系列,它可以抓住容量.我怎么得到"可用"?谢谢!

my @df = qx (df -k /tmp);
my $cap;
foreach my $df (@df)
        {
         ($cap) =($df =~ m!(\d+)\%!);
        };

print "$cap\n";
Run Code Online (Sandbox Code Playgroud)

jm6*_*666 11

简单的perl方式:

perl -MFilesys::Df -e 'print df("/tmp")->{bavail}, "\n"'
Run Code Online (Sandbox Code Playgroud)

  • +1这是唯一合适的答案.这是一个系统调用(`statvfs`等),所以使用库来直接访问结构化数据,而不是正则表达式!解析`df`文本输出就像解析`ls`文本输出一样愚蠢,因为它会中断.GNU coreutils`df`喜欢将文件系统名称放在自己的行上,当它变得太长时,正则表达式解析解决方案都没有考虑到这一点.系统调用首先没有这个问题. (3认同)

Sch*_*ern 5

这样做的好处是可以为您查询有关每个文件系统的所有信息.

# column headers to be used as hash keys
my @headers = qw(name size used free capacity mount);

my @df = `df -k`;
shift @df;  # get rid of the header

my %devices;
for my $line (@df) {
    my %info;
    @info{@headers} = split /\s+/, $line;  # note the hash slice
    $info{capacity} = _percentage_to_decimal($info{capacity});
    $devices{ $info{name} } = \%info;
}

# Change 12.3% to .123
sub _percentage_to_decimal {
    my $percentage = shift;
    $percentage =~ s{%}{};
    return $percentage / 100;
}
Run Code Online (Sandbox Code Playgroud)

现在,每个设备的信息都是散列的哈希值.

# Show how much space is free in device /dev/ad4s1e
print $devices{"/dev/ad4s1e"}{free};
Run Code Online (Sandbox Code Playgroud)

这不是最简单的方法,但它是使用df信息的最常用的方法,将它们放在一个可以根据需要传递的漂亮数据结构中.这比将它全部切割成单个变量以及它应该习惯的技术要好.

更新:要获得具有> 60%容量的所有设备,您将遍历散列中的所有值并选择容量大于60%的那​​些值.除了容量存储为类似"88%"的字符串,这对比较没有用.我们可以在这里删除%,但是我们会在任何想要使用它的地方做到这一点.最好先预先标准化您的数据,这样可以更轻松地使用.存储格式化数据是一个红色标记.所以我修改了上面的代码来读取,df将容量从88%改为.88.

现在它更容易使用.

for my $info (values %devices) {
    # Skip to the next device if its capacity is not over 60%.
    next unless $info->{capacity} > .60;

    # Print some info about each device
    printf "%s is at %d%% with %dK remaining.\n",
        $info->{name}, $info->{capacity}*100, $info->{free};
}
Run Code Online (Sandbox Code Playgroud)

我选择在这里使用printf而不是插值,因为这样可以更容易地看到输出时字符串的外观.