Perl unix df上的正则表达式帮助

Perl unix df上的正则表达式帮助,perl,Perl,我需要一些帮助来调整代码,以便在此unixdf输出中查找另一个属性: 前 到目前为止,我可以提取容量,但现在我想增加可用性 这是我的perl行,它获取了容量。我如何获得“效用”??谢谢 my @df = qx (df -k /tmp); my $cap; foreach my $df (@df) { ($cap) =($df =~ m!(\d+)\%!); }; print "$cap\n"; 你有没有试过简单地将空格分开,然后取第4列和第5

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

到目前为止,我可以提取容量,但现在我想增加可用性

这是我的perl行,它获取了容量。我如何获得“效用”??谢谢

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

print "$cap\n";

你有没有试过简单地将空格分开,然后取第4列和第5列

my @cols = (split(/\s+/, $_));
my $avail = $cols[3];
my $cap   = $cols[4];

(当然,如果设备名称中有空格,则会失败…

Us split,并从结果数组中获取参数。例如

my @values = split /\s+/, $df;
my $avail = $values[3];
或:


我认为最好是分开行,跳过第一行。既然您不介意使用
@df
$df
,我也不介意:

my @df = qx(df -k /tmp);
shift @df;                # Lose df heading line
foreach my $df (@df)
{
    my($system, $size, $used, $avail, $capacity, $mount) = split / +/, $df;
    ....
}

这将同时提供所有字段。现在,您只需要解释“G”并丢失“%”等。这里的主题有很多变化。我会保留第一行,因为它提供了一个很好的标题:

foreach my $device ( @df ) {
    next unless $device =~ m{^/};
    my( $filesystem, $size, $used, $avail, $cap, $mounted ) = split /\s+/, $device;
    # you take it from there.... ;)
}
$ perl -E '$,=" "; open my $fh, "-|", "df -k /tmp"; while(<$fh>) { @a=split; say @a[3,4]}' $perl-E'$,='';打开我的$fh、“-|”和“df-k/tmp”; while(){@a=split;说@a[3,4]} 仔细想想,这要干净得多:

$ df -k /tmp | perl -naE '$,="\t"; say @F[3,4]' Available Capacity 20862392 92% $df-k/tmp | perl-naE'$,=“\t”;说@F[3,4]' 可用容量 20862392 92% 最后一个想法:根本不要使用perl:

$ df -h /tmp | tr -s ' ' '\t' | cut -f 3,4 $df-h/tmp | tr-s'\t'| cut-f3,4 或

$df-h/tmp | awk'{打印$3“\t”$4}'
它的优点是为您生成一个好的数据结构,以便查询关于每个文件系统的所有信息

# 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;
}
现在,每个设备的信息都在散列中

# Show how much space is free in device /dev/ad4s1e
print $devices{"/dev/ad4s1e"}{free};
这不是最简单的方法,但它是处理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};
}
我选择在这里使用printf而不是插值,因为它使输出时更容易看到字符串的样子。

简单的perl方法:

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

你为什么用正则表达式?你知道你想要哪一列,所以只要根据它的索引抓取该列。@William:你没听说吗?正则表达式是所有问题的答案…您可能希望使用
df-P
(如果您使用的是GNU df)实现POSIX的可移植性..正则表达式比硬编码列偏移量更健壮。对格式的任何细微更改都会更改列偏移量、df的不同风格和版本以及不同的格式标志,而一个合适的正则表达式将经受住大多数格式更改。在该拆分中,您需要一个
+
df
并不总是在其colums@Mat
split
自动执行该操作。@TLP,Mat是对的,您错了
perl-E'say((split/\s/,“a\x20\x20\x20b c d”)[3])
打印
b
而不是
d
split'
删除前导空格和空格上的拆分<代码>拆分/\s+/在空白处拆分
split/\s/
在单个空白字符上拆分。@Mat自动拆分的是
'
。@Schwem-我喜欢这样。作为一个新手,我愿意学习其他一些技巧。你能详细说明引用的设备名称的用法吗?它是我的无值索引吗?这就是我的解释吗?谢谢我想使用if语句设置一个阈值。例如,如果我想要容量>60%,我该怎么做?@jdamae是的,
%devices
由设备名称(df称之为文件系统)键入。@jdamae我添加了一个示例,说明如何搜索哈希并使用它。+1这是唯一合适的答案。这是一个系统调用(
statvfs
等),因此使用库直接访问结构化数据,而不是正则表达式!解析
df
文本输出与解析
ls
文本输出一样愚蠢,因为它会中断。GNUCoreutils
df
喜欢在文件系统名称过长时将其放在自己的行中,没有一个正则表达式解析解决方案考虑到这一点。系统调用一开始就没有这个问题。
# Show how much space is free in device /dev/ad4s1e
print $devices{"/dev/ad4s1e"}{free};
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};
}
perl -MFilesys::Df -e 'print df("/tmp")->{bavail}, "\n"'