команды awk с помощью массива

Month Sales
January 20
February 30
March 43
February 34
January 12
June 89
May 97
June 60
July 23
August 13
August 45
October 56
October 45
November 34

Запишите awk сценарий для нахождения месяцев без продаж.

У нас должен быть массив, содержащий имена всех месяцев, и мы должны проверить его с array[$1]? Я попробовал это, но я продолжаю портить синтаксис.

echo 'January 
February
March
April
May
June
July
August
September
October
November
December' | 
awk '
BEGIN{ flag=0;}
{arr[month++]=$0}
{ 
    sales[$1]+=$2;
}
END
{
    for(month in arr)
    {
        if(month in sales)
            flag=1;

        if(flag==0) 
            print month;
    }
}'

Это - то, что я попробовал до сих пор. Я продолжаю получать ошибку при высказывании:

awk: cmd. line:8: END blocks must have an action part
0
задан 1 September 2019 в 20:06

1 ответ

Я думаю , я вижу, куда Вы идете с этим - но это может быть упрощено довольно много

  • канал на имена этих 12 месяцев через стандартный вход и использовать их в качестве индексов массива

  • , читает файл ежемесячных продаж, удаляя каждый месяц, когда мы видим его

  • печать независимо от того, что месяцы остаются в конце

, прием должен использовать - в качестве специального имени файла для сообщения awk, которые заказывают для чтения стандартного входа и файла, и NR==FNR как тест для того, читаем ли мы stdin:

printf '%s\n' January February March April May \
    June July August September October November December | awk '
      NR==FNR {sales[$1]; next} {delete sales[$1]} END {for(m in sales) print m}
    ' - sales.txt
December
September
April

Примечание, что Вы не должны присваивать значения элементам массива - просто присваивающиеся индексы, достаточно для определения массива.

, С другой стороны, Вы могли определить массив в BEGIN блок:

awk '
  BEGIN {
    sales["January"]; sales["February"]; sales["March"]; 
    sales["April"]; sales["May"]; sales["June"]; 
    sales["July"]; sales["August"]; sales["September"]; 
    sales["October"]; sales["November"]; sales["December"];
  } 
  {delete sales[$1]}
  END {
    for(m in sales) print m
  }' sales.txt
<час>

Несколько альтернативных подходов KISS:

(1) создают массив, индексированный месяцами в BEGIN блок, присваивают значения элементам, затем выполняют итерации по массиву в END блок и печатают любого, значение которого является нулем

awk '
  BEGIN {
    sales["January"]; sales["February"]; sales["March"]; 
    sales["April"]; sales["May"]; sales["June"]; 
    sales["July"]; sales["August"]; sales["September"]; 
    sales["October"]; sales["November"]; sales["December"];
  } 
  NR > 1 {
    sales[$1] += $2;
  }
  END {
    for (m in sales) {
      if (sales[m] == 0) print m;
    }
  }
' sales.txt

или (2), создают массив на лету из sales.txt файл, затем выполняют итерации за все месяцы в END блок и печатают любые недостающие индексы

awk '
  NR > 1 {
    sales[$1] += $2
  } 
  END {
    n = split("January February March April May June July August September October November December", months); 
    for (i=1;i<=n;i++) {
      if (!(months[i] in sales)) print months[i]
    }
  }
' sales.txt
0
ответ дан 23 October 2019 в 03:47

Другие вопросы по тегам:

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