Awk массив печатает элементы в неожиданном порядке - PullRequest
0 голосов
/ 22 октября 2019

Я использую awk для захвата метки времени из набора данных и распечатки значения (памяти), связанного с этой меткой времени.

Следующий код awk хорошо работает для достижения этой цели.

awk '
/show memory compare start/     {getline
                                 start_time = $0;
                                }
/show memory compare end/       {getline
                                 end_time = $0;
                                }
/mibd_interface/{
        print start_time, $3, "\n" end_time, $4
}' snmpoutput.txt

Thu Sep 19 14:38:06.400 WIB 8670334
Thu Sep 19 14:40:56.123 WIB 8484152
Thu Sep 19 14:43:07.946 WIB 8369050
Thu Sep 19 14:45:27.916 WIB 8514825
Thu Sep 19 14:46:28.464 WIB 8446906
Thu Sep 19 14:50:10.422 WIB 8264885
Thu Sep 19 14:50:44.374 WIB 8264884
Thu Sep 19 14:55:05.760 WIB 8264960

После помещения этих данных в массив и печати их элементы отображаются не по порядку.

Я ввел порядок появления в крайнем правом столбце, сравнивая этот вывод с требуемым выводом выше.

awk '
/show memory compare start/     {getline
                                 start_time = $0;
                                }
/show memory compare end/       {getline
                                 end_time = $0;
                                }

/mibd_interface/{mem_stats[start_time]=$3; mem_stats[end_time]=$4} END {for (time in mem_stats) {printf "%s => %s\n",time,mem_stats[time]}}' snmpoutput.txt

Thu Sep 19 14:55:05.760 WIB => 8264960  8
Thu Sep 19 14:45:27.916 WIB => 8514825  4 
Thu Sep 19 14:43:07.946 WIB => 8369050  3
Thu Sep 19 14:40:56.123 WIB => 8484152  2 
Thu Sep 19 14:50:44.374 WIB => 8264884  7
Thu Sep 19 14:38:06.400 WIB => 8670334  1  
Thu Sep 19 14:50:10.422 WIB => 8264885  6
Thu Sep 19 14:46:28.464 WIB => 8446906  5

DATASET

(отправил образец, так как полный набор данных слишком велик)

Одна итерация

xr_lab#show memory compare start
Thu Sep 19 14:38:06.400 WIB   
Successfully stored memory snapshot in /var/log/malloc_dump_memcmp_start.out
xr_lab#
xr_lab#
xr_lab#show memory compare end
Thu Sep 19 14:40:56.123 WIB   
Successfully stored memory snapshot in /var/log/malloc_dump_memcmp_end.out
xr_lab#
xr_lab#show memory compare report
Thu Sep 19 14:41:08.084 WIB

PID    NAME                     MEM BEFORE    MEM AFTER  DIFFERENCE MALLOCS-NEW
-------------------------------------------------------------------------------

2550   sysdb_svr_local          7881443     7878256     -3187       87391
7582   mibd_interface           8670334     8484152     -186182     267657

Вторая итерация

xr_lab#show memory compare start
Thu Sep 19 14:43:07.946 WIB   
Successfully stored memory snapshot in /var/log/malloc_dump_memcmp_start.out
xr_lab#
xr_lab#
xr_lab#
xr_lab#show memory compare end
Thu Sep 19 14:45:27.916 WIB   
Successfully stored memory snapshot in /var/log/malloc_dump_memcmp_end.out
xr_lab#
xr_lab#
xr_lab#show memory compare report
Thu Sep 19 14:45:42.091 WIB

PID    NAME                     MEM BEFORE    MEM AFTER  DIFFERENCE MALLOCS-NEW
-------------------------------------------------------------------------------
6777   ospf                     24294569    24283592    -10977      227389
7582   mibd_interface           8369050     8514825     145775      126259

Могу ли я узнать, почему элементы печатаются не по порядку, и как это исправить?

Спасибо.

Ответы [ 2 ]

1 голос
/ 22 октября 2019

Могу ли я узнать, почему элементы печатаются не по порядку, и как это исправить?

В стандарте сказано следующее:

Язык awk предоставляет массивы, которые используются для хранения чисел или строк. Массивы не должны быть объявлены. Сначала они должны быть пустыми, а их размеры должны изменяться динамически. Индексы, или идентификаторы элементов, являются строками , обеспечивающими возможность ассоциативного массива типа .

for (variable in array)

, который должен повторяться, присваивая каждому индексу массива переменную в неопределенном порядке .

Итак, мы знаемчто массив в awk является ассоциативным массивом , не более чем комбинацией ключ-значение-пара. Классическим примером в мире программирования является двоичное дерево, такое как C ++ std::map. Обычно для эффективного обхода и поиска в массиве необходимо наложить порядок, однако стандартный awk не дает нам возможности определить такой порядок. Стандарт оставляет порядок ключей свободным выбором для тех, кто использует awk. Именно поэтому он заявляет, что for (variable in array) будет проходить массив в неопределенном порядке.

GNU awk, с другой стороны, позволяет определять порядок ключей на глобальном уровне, используя переменную-массив PROCINFO["sorted_in"], и на локальном уровне, используя * 1032. *asorti(source [, dest [, how ] ]) функция. Последний будет хранить ключи массива source в массиве с целочисленным индексом dest. Последний заполняется так, что порядок клавиш определяется функцией how (dest[1] < dest[2] < dest[3] < ... с how, определяющим <).

Если вы не хотите использовать функции GNU awk ивы знаете, что отсортировали ввод, тогда вы можете использовать два массива. Тот, который отслеживает порядок ключей, и тот, который отслеживает значения ключей:

{ key_order[++c]="key"
  data["key"] = "value" }
END { for(i=1;i<=c;++i) print data[key_order[i]] }
1 голос
/ 22 октября 2019

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

1-е решение: Учитывая, что временные метки никогда не будут одинаковыми для любыхдругие строки, если это так, тогда просто выполните:

awk '
/show memory compare start/{
  getline
  start_time = $0;
  b[++count]=start_time
}
/show memory compare end/{
  getline
  end_time = $0;
  b[++count]=end_time

}
/mibd_interface/{
  mem_stats[start_time]=$3
  mem_stats[end_time]=$4
}
END{
  for(i=1;i<=count;i++){
    printf "%s => %s\n",b[i],mem_stats[b[i]]
  }
}' Input_file


2-е решение: ИЛИ будет считать, что у вас может быть то же самоевременная метка иногда в журналах:

awk '
/show memory compare start/{
  getline
  start_time = $0;
  if(!a[start_time]++){
      b[++count]=start_time
  }
}
/show memory compare end/{
  getline
  end_time = $0;
  if(!a[end_time]++){
      b[++count]=end_time
  }
}
/mibd_interface/{
  mem_stats[start_time]=$3
  mem_stats[end_time]=$4
}
END{
  for(i=1;i<=count;i++){
    printf "%s => %s\n",b[i],mem_stats[b[i]]
  }
}'  Input_file


Проверенный код с файлом Input_file:

cat Input_file
xr_lab#show memory compare start
Thu Sep 19 14:38:06.400 WIB   
Successfully stored memory snapshot in /var/log/malloc_dump_memcmp_start.out
xr_lab#
xr_lab#
xr_lab#show memory compare end
Thu Sep 19 14:40:56.123 WIB   
Successfully stored memory snapshot in /var/log/malloc_dump_memcmp_end.out
xr_lab#
xr_lab#show memory compare report
Thu Sep 19 14:41:08.084 WIB

PID    NAME                     MEM BEFORE    MEM AFTER  DIFFERENCE MALLOCS-NEW
-------------------------------------------------------------------------------

2550   sysdb_svr_local          7881443     7878256     -3187       87391
7582   mibd_interface           8670334     8484152     -186182     267657


xr_lab#show memory compare start
Thu Sep 19 14:43:07.946 WIB   
Successfully stored memory snapshot in /var/log/malloc_dump_memcmp_start.out
xr_lab#
xr_lab#
xr_lab#
xr_lab#show memory compare end
Thu Sep 19 14:45:27.916 WIB   
Successfully stored memory snapshot in /var/log/malloc_dump_memcmp_end.out
xr_lab#
xr_lab#
xr_lab#show memory compare report
Thu Sep 19 14:45:42.091 WIB

PID    NAME                     MEM BEFORE    MEM AFTER  DIFFERENCE MALLOCS-NEW
-------------------------------------------------------------------------------
6777   ospf                     24294569    24283592    -10977      227389
7582   mibd_interface           8369050     8514825     145775      126259

Вывод выглядит следующим образом:

Thu Sep 19 14:38:06.400 WIB    => 8670334
Thu Sep 19 14:40:56.123 WIB    => 8484152
Thu Sep 19 14:43:07.946 WIB    => 8369050
Thu Sep 19 14:45:27.916 WIB    => 8514825
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...