AWK для поиска первых 3 значений

top -bcn1 -w512

Элегантным решением является использование опции -w [number]. Согласно справочной странице, максимальная ширина составляет 512 символов, поэтому вам понадобится другое решение для всего, что превышает это значение. Предположительно, вы также хотите видеть полную длину команд, поэтому используйте опцию -c. Нам нужно запустить topв "пакетном режиме", -b, иначе он продолжит обрезать команды с "+". Пакетный режим создает беспорядок, потому что он выводит все задания каждую секунду, поэтому мы можем использовать опцию -n1для вывода только одного экземпляра.

Дополнительную информацию см. на странице man top .

0
30.07.2019, 12:04
2 ответа

В следующем Perl-скрипте используется структура данных, называемая Hash -of -Arrays (или HoA ). Хэш (%sites )имеет ключ, полученный из первых трех полей (site,region,town ), и каждый элемент хеша представляет собой массив, содержащий ВСЕ итоги для этого конкретного ключа.

Он читается в каждой строке для создания HoA -, удаляя все начальные или конечные пробелы и игнорируя все пустые строки. Он также игнорирует комментарии (все, что начинается с символа #), потому что это тривиально легко сделать, и я думаю, что полезно иметь возможность комментировать данные в текстовых файлах данных.

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

#!/usr/bin/perl

my %sites=();

while(<>) {
  chomp;
  s/#.*//;        # strip comments #
  s/^\s*|\s*$//g; # strip leading and trailing spaces
  next if (/^$/); # skip blank lines

  my($site,$region,$town,$total) = split /,/;
  my $key = "$site,$region,$town";

  push @{ $sites{$key} }, $total;
}

foreach my $k (sort keys %sites) {
  @{ $sites{$k} } = reverse sort @{ $sites{$k} };
  print $k. ": ". join(", ",@{ $sites{$k}}[0..2] ), "\n";
};

образец вывода:

$./jon.pl input.txt
site1,North,Bristol: 996776, 9776, 6776
site2,South,Guildford: 99392, 392, 2392
site2,South,London: 99381, 381, 2381
site3,Central,Birmingham: 992628, 5628, 2628
site3,Wales,Cardiff: 99834, 9834, 834
site3,Wales,Swansea: 991796, 3796, 21796
site5,South,Guildford: 99338, 338, 2338
site5,South,London: 99266, 3266, 266
site5,South,Windsor: 99359, 359, 2359
site5,West,Bristol: 997700, 9700, 7700

input.txtсодержит предоставленные вами образцы данных, скопированные несколько раз, с отредактированными в копиях суммами.

Вывод можно легко изменить, чтобы сделать его более красивым, или вывести по одной строке для каждой общей (подсказки, выполнить цикл по элементам массива [0..2], а не соединять ()их ).


Кстати, возможно реализовать что-то подобное в awk, но это намного проще сделать в perl.

1
28.01.2020, 03:25

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

BEGIN { FS = "," }

{
    key = sprintf("%s,%s,%s", $1, $2, $3)
    value = $4

    for (i = 1; i <= 3; ++i)
        if (values[i] == "" || values[i] < value) {
            tmp = values[i]
            values[i] = value
            value = tmp

            tmp = keys[i]
            keys[i] = key
            key = tmp
        } else break
}

END {
    for (i = 1; i <= 3; ++i)
        printf("%s,%d\n", keys[i], values[i])
}

Здесь используются два массива, valuesи keys. Для каждого считанного значения(value = $4)значение сравнивается с каждым значением в values, чтобы определить, больше ли оно любого из них. Если это так, «текущее значение»(value)заменяется значением в values[i]и , это значение «пузырится» вниз по массиву. Массив keysсинхронизируется с массивом values.

Тестирование:

$ cat file
A1,B2,C3,35
A4,B5,C6,607
A7,B8,C9,159
A10,B11,C12,100
A13,B14,C15,116
A16,B17,C18,688
A19,B20,C21,346
A22,B23,C24,277
A25,B26,C27,931
A28,B29,C30,552
A31,B32,C33,605
A34,B35,C36,109
$ awk -f script.awk file
A25,B26,C27,931
A16,B17,C18,688
A4,B5,C6,607
0
28.01.2020, 03:25

Теги

Похожие вопросы