AWK, посчитайте частоту имен машин в нескольких файлах журнала - PullRequest
0 голосов
/ 02 июля 2018

У меня есть файлы журналов не менее 100G. Структура каталогов файла журнала выглядит следующим образом:

drwxrwxr-x 2 griyn griyn 4096 Jul  2 14:33 lcdc-0615-00.log
drwxrwxr-x 2 griyn griyn 4096 Jun 29 14:22 lcdc-0615-01.log
drwxrwxr-x 2 griyn griyn 4096 Jun 28 21:25 lcdc-0615-02.log
drwxrwxr-x 2 griyn griyn 4096 Jun 28 21:25 lcdc-0615-03.log
drwxrwxr-x 2 griyn griyn 4096 Jun 28 21:25 lcdc-0615-04.log
drwxrwxr-x 2 griyn griyn 4096 Jun 28 21:25 lcdc-0615-05.log
drwxrwxr-x 2 griyn griyn 4096 Jun 28 21:25 lcdc-0615-06.log

И в каждом каталоге

[griyn@cp01-vm-griyn test_data]$ cd lcdc-0615-00.log/
[griyn@cp01-vm-griyn lcdc-0615-00.log]$ ll
total 361216
-rw-rw-r-- 1 griyn griyn 184936785 Jun 28 21:19 yq01-spi-mx0.yq01
-rw-rw-r-- 1 griyn griyn 184936680 Jun 28 21:20 yq01-spi-mx22.yq01

содержимое файла журнала здесь,

  1 peer_addr[yq01-spi-mx38:29129]
  2 peer_addr[yq01-spi-mx38:29129]
  3 peer_addr[yq01-ps-beehive-agent3677:29082]
  4 peer_addr[yq01-spi-mx38:29129]
  5 peer_addr[yq01-spi-mx38:29129]
  6 peer_addr[yq01-spi-mx38:29129]
  7 peer_addr[yq01-ps-beehive-agent3677:29082]
  8 peer_addr[yq01-spi-mx38:29129]
  9 peer_addr[yq01-spi-mx38:29129]
 10 peer_addr[yq01-ps-beehive-agent3677:29082]
 11 peer_addr[yq01-spi-mx38:29129]
 12 peer_addr[yq01-ps-beehive-agent3677:29082]
 13 peer_addr[yq01-spi-mx38:29129]
 14 peer_addr[yq01-ps-beehive-agent3677:29082]
 15 peer_addr[yq01-spi-mx38:29129]
 16 peer_addr[yq01-spi-mx38:29129]
 17 peer_addr[yq01-ps-beehive-agent3677:29082]
 18 peer_addr[yq01-spi-mx38:29129]
 19 peer_addr[yq01-spi-mx38:29129]
 20 peer_addr[yq01-ps-beehive-agent3677:29082]
 21 peer_addr[yq01-spi-mx38:29129]
 22 peer_addr[yq01-ps-beehive-agent3677:29082]
 23 peer_addr[yq01-spi-mx38:29129]

Я хочу посчитать частоту имен машин в нескольких файлах журнала по сценарию оболочки. Я использую AWK так:

awk -F'[]:[]' '/peer_addr/{map[$2]+=1} END{for(key in map) {sum+=map[key];printf("%-15s %s\n", key, map[key]);} print "sum:",sum}' ${log_file_dir}/${log_path} >> ./conclusion/sum.log &

Видимо, нам нужна структура карты для сохранения и обновления результата. Тогда у меня есть проблема, что структура карты в AWK просто используется в self AWK. Я не могу суммировать результат в нескольких файлах журнала.

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

Есть ли у вас более эффективный подход?

1 Ответ

0 голосов
/ 02 июля 2018

Если у вас большое количество файлов, намного превышающее максимально допустимый список аргументов, вы можете использовать Awk следующим образом:

  1. Создайте файл со всеми файлами, которые вы хотите обработать.

    $ find <logroot> -type f -iname '*.yq01' > <logroot>/logfiles.txt
    
  2. Используйте awk для создания самого списка ARGV:

    $ awk -F'[]:[]' '(NR==FNR){ARGV[ARGC++]=$0; next}
                     /peer_addr/{map[$2]++}
                     END{ for(key in map) {
                             sum+=map[key];
                             printf("%-15s %s\n", key, map[key]);
                          }
                          print "sum:",sum }
                    ' <logroot>/logfiles.txt
    

ARGC: Количество элементов в массиве ARGV.

ARGV: Массив аргументов командной строки, исключая опции и программный аргумент, пронумерованный от нуля до ARGC-1. Аргументы в ARGV могут быть изменены или добавлены; ARGC может быть изменено. Когда заканчивается каждый входной файл, awk будет обрабатывать следующий ненулевой элемент ARGV, вплоть до текущего значения ARGC-1 включительно, как имя следующего входного файла. , Таким образом, установка элемента ARGV в ноль означает, что он не должен рассматриваться как входной файл. Имя '-' обозначает стандартный ввод. Если аргумент соответствует формату операнда присваивания, этот аргумент должен рассматриваться как присвоение, а не как аргумент файла.

Источник: awk Стандарт POSIX

параллельная обработка:

Если вы хотите выполнить некоторую параллельную обработку, вас может заинтересовать Параллельная GNU :

$ cat <logroot>/logfiles.txt              \
   | parallel --jobs 4 ./process_files.sh \
   | awk '{map[$1]+=$2}
          END{ for(key in map) {
                  sum+=map[key];
                  printf("%-15s %s\n", key, map[key]);
               }
               print "sum:",sum
             }'

с process_files.sh:

#!/usr/bin/env bash
awk -F'[]:[]' '(NR==FNR){ARGV[ARGC++]=$0; next}
               /peer_addr/{map[$2]++}
               END{ for(key in map) {
                      sum+=map[key];
                      printf("%-15s %s\n", key, map[key]);
                    }}' "$@"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...