многомерный массив в awk

#linux #unix #awk

#linux #unix #awk

Вопрос:

У меня есть небольшая база данных, как показано ниже:

     10/08/2011      laptop  4
    10/08/2011      laptop  2
    10/08/2011      desktop 2
    10/08/2011      laptop  1
    10/08/2011      pen     5
    10/08/2011      pen     2
    10/08/2011      waterbottle     8
    10/2/2011       ring    11
    10/02/2011      waterbottle     5
    10/2/2011       ring    2
    10/2/2011       ring    4
    10/2/2011       keyboard        20
    10/2/2011       keyboard        10
    11/2/2011       mouse   10
    11/2/2011       mouse   4
    11/2/2011       mouse   10
    11/2/2011       door    55
  

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

 awk '{arr[$1,$2]  ;}END {for (i in  arr){ for (j in arr[$i]){print arr[$i,$j];}}}' data
  

Есть идеи, как это сделать?? Я буду признателен за вашу помощь. Спасибо

Ответ №1:

Массивы Awk — это сопоставления ключей со значениями. То, что вы создали, пытаясь получить многомерный массив, на самом деле является массивом с более сложными ключами. Таким образом, вы должны перебирать объединенные ключи, а не индексы, которые вы использовали для их построения:

 awk '{ arr[$1,$2]   } END {for (key in  arr){ print arr[key] } }' data
  

Комментарии:

1. Я полностью согласен с этим решением. Для решения этой проблемы не требуется ничего многомерного, и это правильная итерация.

Ответ №2:

Вы можете сделать это с помощью GNU awk 4.0:

 awk 'END {
  for (D in d)
    for (E in d[D])
      print E, d[D][E]
  }
{ 
  d[$1][$2]  
  }' infile  
  

В большинстве случаев решения, опубликованного @Michael J. Barber, будет достаточно.

С GNU awk 4.0 вы также можете легко упорядочить значения (в этом примере упорядоченные по количеству проданных):

 % awk 'END {
  PROCINFO["sorted_in"] = "@val_num_desc"
  for (D in d) {
    split(D, t, SUBSEP)
    print t[1], t[2], d[D]
    }
  }
{
  d[$1, $2]  
  }' infile  
11/2/2011 mouse 3
10/2/2011 ring 3
10/08/2011 laptop 3
10/2/2011 keyboard 2
10/08/2011 pen 2
10/08/2011 desktop 1
11/2/2011 door 1
10/08/2011 waterbottle 1
10/02/2011 waterbottle 1