Помощь по регулярному выражению в Unix DF - PullRequest
2 голосов
/ 15 июня 2011

Мне нужна помощь в настройке моего кода для поиска другого атрибута в этом выводе Unix df:

Ex.

Filesystem     Size    Used   Avail Capacity  Mounted on
/dev/ad4s1e     61G     46G    9.7G    83%    /home

Пока что я могу извлекать емкость, но теперь я хочу добавить Свободно.

Вот моя линия Perl, которая захватывает емкость. Как я могу получить "Свободно" ?? Спасибо!

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

print "$cap\n";

Ответы [ 7 ]

11 голосов
/ 15 июня 2011

Простой способ Perl:

perl -MFilesys::Df -e 'print df("/tmp")->{bavail}, "\n"'
5 голосов
/ 15 июня 2011

Это имеет смысл создать хорошую структуру данных, чтобы вы могли запрашивать всю информацию о каждой файловой системе.

# 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% до 0,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, а не интерполяцию, потому что это немного облегчает просмотр того, как будет выглядеть строка при выводе.

2 голосов
/ 15 июня 2011

Вместо этого мы разделяем и получаем аргументы из полученного массива. Э.Г.

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

Или:

($filesystem, $size, $used, $avail, $cap, $mount) = split /\s/, $df;
2 голосов
/ 15 июня 2011

Вы пробовали просто разбить пробел и взять 4-й и 5-й столбцы?

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

(Сбой, если в именах устройств есть пробелы ...)

1 голос
/ 15 июня 2011

Много вариаций на тему здесь. Я бы сохранил первую строку, так как она дает хороший заголовок:

$ perl -E '$,=" "; open my $fh, "-|", "df -k /tmp"; 
  while(<$fh>) { @a=split; say @a[3,4]}'

Если подумать, это намного чище:

$ df -k /tmp | perl -naE '$,="\t"; say @F[3,4]'
Available       Capacity
20862392        92%

Заключительная мысль: вообще не используйте perl:

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

или

$ df -h /tmp | awk '{print $3 "\t" $4}'
1 голос
/ 15 июня 2011
foreach my $device ( @df ) {
    next unless $device =~ m{^/};
    my( $filesystem, $size, $used, $avail, $cap, $mounted ) = split /\s+/, $device;
    # you take it from there.... ;)
}
1 голос
/ 15 июня 2011

Я думаю, что лучше разделить строки, пропустив первую строку.Так как вы не возражаете против использования @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» и потерять «%» и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...