首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过打印每列中出现的前5个数据元素来增强awk脚本

通过打印每列中出现的前5个数据元素来增强awk脚本
EN

Stack Overflow用户
提问于 2012-01-30 12:24:01
回答 2查看 251关注 0票数 4

我有一个awk脚本,它处理一个csv文件并生成一个报告,该报告统计包含数据/A-Za-z0-9/的每一列的行数。我想要做的是增强脚本,并打印每列中重复最多的5个数据元素。

以下是示例数据:

代码语言:javascript
复制
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贡献最大的当前脚本:

代码语言:javascript
复制
$ 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])
      }
    }
  }
}

这是当前的输出:

代码语言:javascript
复制
$ 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

这是所需的输出:

代码语言:javascript
复制
$ 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。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-01-30 15:26:07

以下脚本既是可扩展的,也是可伸缩的,因为它可以处理任意数量的列。Nothing是硬编码的

代码语言:javascript
复制
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

输出

代码语言:javascript
复制
$ ./report
Food                            9
Type                            5
    Meat                        2
    Bread                       1
    Vegetable                   2
    Fruit                       2
    Fish                        1
Spicy                           2
    Yes                         2
    No                          6
票数 3
EN

Stack Overflow用户

发布于 2012-01-30 13:12:15

不是一个完整的解决方案,但有些东西可以让你开始-

代码语言:javascript
复制
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 

测试:

代码语言:javascript
复制
[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
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9059324

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档