Улучшите сценарий awk, печатая 5 лучших элементов данных из каждого столбца - PullRequest
3 голосов
/ 30 января 2012

У меня есть скрипт awk, который обрабатывает файл csv и создает отчет, в котором подсчитывается количество строк для каждого столбца, названных в поле заголовка, которые содержат данные / [A-Za-z0-9] /.Я хотел бы улучшить сценарий и распечатать 5 самых повторяющихся элементов данных в каждом столбце.

Вот пример данных:

Food|Type|Spicy
Broccoli|Vegetable|No
Lettuce|Vegetable|No
Spinach|Vegetable|No
Habanero|Vegetable|Yes
Swiss Cheese|Dairy|No
Milk|Dairy|No
Yogurt|Dairy|No
Orange Juice|Fruit|No
Papaya|Fruit|No
Watermelon|Fruit|No
Coconut|Fruit|No
Cheeseburger|Meat|No
Gorgonzola|Dairy|No
Salmon|Fish|
Apple|Fruit|No
Orange|Fruit|No
Bagel|Bread|No
Chicken|Meat|No
Chicken Wings|Meat|Yes
Pizza||No

Это текущий сценарий, который SiegeXвнесли существенный вклад:

$ cat matrix2.awk 
NR==1{
  for(i=1;i<=NF;i++)
    head[i]=$i
  next
}
{
  for(i=1;i<=NF;i++)
  {
    if($i && !arr[i,$i]++)
      n[i]++
    if(arr[i,$i] > 1)
      f[i]=1
  }
}
END{
  for(i=1;i<=length(head);i++) {
    printf("%-6d%s\n",n[i],head[i])
    if(f[i]) {
      for(x in arr) {
        split(x,b,SUBSEP)
        if(b[1]==i && b[2])
          printf("% -6d %s\n",arr[i,b[2]],b[2])
      }
    }
  }
}

Это текущий вывод:

$ awk -F "|" -f matrix2.awk testlist.csv 
20    Food
6     Type
 6     Fruit
 4     Vegetable
 3     Meat
 1     Fish
 4     Dairy
 1     Bread
2     Spicy
 17    No
 2     Yes

И это желаемый вывод:

$ awk -F "|" -f matrix2.awk testlist.csv 
20    Food
6     Type
 6     Fruit
 4     Vegetable
 4     Dairy
 3     Meat
 1     Fish
2     Spicy
 17    No
 2     Yes

Единственное, что осталось, что яЯ хотел бы добавить общую функцию, которая ограничивает вывод каждого столбца 5-ю наиболее дублируемыми полями.Как упоминалось ниже, столбчатая версия sort | uniq -c | sort -nr | head -5.

Ответы [ 2 ]

2 голосов
/ 30 января 2012

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

awk -F'|' '
NR==1{
  for(i=1;i<=NF;i++)
    head[i]=$i
  next
}
{
  for(i=1;i<=NF;i++)
  {
    if($i && !arr[i,$i]++)
      n[i]++
    if(arr[i,$i] > 1)
      f[i]=1
  }
}
END{
  for(i=1;i<=length(head);i++) {
    printf("%-32s%d\n",head[i],n[i])
    if(f[i]) {
      for(x in arr) {
        split(x,b,SUBSEP)
        if(b[1]==i && b[2])
          printf("    %-28s%d\n",b[2],arr[i,b[2]])
      }
    }
  }
}' infile

Вывод

$ ./report
Food                            9
Type                            5
    Meat                        2
    Bread                       1
    Vegetable                   2
    Fruit                       2
    Fish                        1
Spicy                           2
    Yes                         2
    No                          6
1 голос
/ 30 января 2012

Не полное решение, но кое-что, с чего можно начать -

awk -F"|" '
NR>1{
        a[$1]++;
        b[$2]++;
        c[$3]++}
END{
        print "Food\t\t\t" length(a); 
        print "Type\t\t\t" length(b); 
        for (x in b) 
            if (x!="") 
            {
                printf ("\t%-16s%s\n",x,b[x]);
            }
        print "Spicy\t\t\t" length(c); 
        for (y in c) 
            if (y!="") 
            {
                printf ("\t%-16s%d\n",y,c[y])
            }
}' testlist.csv 

TEST:

[jaypal:~/Temp] cat testlist.csv 
Food|Type|Spicy
Broccoli|Vegetable|No
Jalapeno|Vegetable|Yes
Salmon|Fish|
Apple|Fruit|No
Orange|Fruit|No
Bagel|Bread|No
Chicken|Meat|No
Chicken Wings|Meat|Yes
Pizza||No

[jaypal:~/Temp] awk -F"|" 'NR>1{a[$1];b[$2]++;c[$3]++}END{print "Food\t\t\t" length(a); print "Type\t\t\t"length(b); for (x in b) if (x!="") printf ("\t%-16s%s\n",x,b[x]) ;print "Spicy\t\t\t"length(c); for (y in c) if (y!="") {printf ("\t%-16s%d\n",y,c[y])}}' testlist.csv 
Food                9
Type                6
    Fruit           2
    Vegetable       2
    Bread           1
    Meat            2
    Fish            1
Spicy               3
    Yes             2
    No              6
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...