免费注册 查看新帖 |

ChinaUnix.net

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 2052 | 回复: 12

[文本处理] 求助大神,多文本统计 [复制链接]

论坛徽章:
0
发表于 2019-01-03 19:03 |显示全部楼层
求助大神,统计多个文件关键字出现的次数,请大神指教如何实现,内容如下:
file1
洲,国,省,市,a
亚洲,中国,宁夏,银川,fsaf
亚洲,中国,辽宁,沈阳,gag
亚洲,中国,河北,石家庄,sgag
亚洲,中国,陕西,西安,eyy
亚洲,中国,陕西,西安,xv

file2
洲,国,省,市,b
亚洲,中国,辽宁,沈阳,xcv
亚洲,中国,宁夏,银川,kryh
亚洲,中国,陕西,西安,la
亚洲,中国,河南,郑州,pwej



file3
洲,国,省,市,c
亚洲,中国,陕西,西安,wow
亚洲,中国,河北,石家庄,cfg
亚洲,中国,甘肃,兰州,cnf
亚洲,中国,陕西,西安,aaww



统计想要的结果
洲,国,省,市,file1,file2,file3
亚洲,中国,宁夏,银川,1,1,0
亚洲,中国,辽宁,沈阳,1,1,0
亚洲,中国,河北,石家庄,1,0,1
亚洲,中国,陕西,西安,2,1,2
亚洲,中国,河南,郑州,0,1,0
亚洲,中国,甘肃,兰州,0,0,1

论坛徽章:
0
发表于 2019-01-09 16:09 |显示全部楼层
本帖最后由 csccyab 于 2019-01-09 16:13 编辑

$ awk -F',' 'FNR>1{a[$1,$2,$3,$4]} FILENAME==ARGV[1]&&FNR>1{a1[$1,$2,$3,$4]++} FILENAME==ARGV[2]&&FNR>1{a2[$1,$2,$3,$4]++} FILENAME==ARGV[3]&&FNR>1{a3[$1,$2,$3,$4]++}END{for (i in a) {split(i,b,SUBSEP); printf "%s,%s,%s,%s,%d,%d,%d\n",b[1],b[2],b[3],b[4],a1,a2,a3}} ' file1 file2 file3
亚洲,中国,河北,石家庄,1,0,1
亚洲,中国,陕西,西安,2,1,2
亚洲,中国,宁夏,银川,1,1,0
亚洲,中国,甘肃,兰州,0,0,1
亚洲,中国,河南,郑州,0,1,0
亚洲,中国,辽宁,沈阳,1,1,0

论坛徽章:
0
发表于 2019-01-10 11:09 |显示全部楼层
回复 2# csccyab

这个我执行之后报错 awk: cmd. line:1: (FILENAME=file3 FNR=5) fatal: attempt to use array `a1' in a scalar context

论坛徽章:
0
发表于 2019-01-10 11:09 |显示全部楼层
回复 2# csccyab

这个我执行之后报错 awk: cmd. line:1: (FILENAME=file3 FNR=5) fatal: attempt to use array `a1' in a scalar context

论坛徽章:
0
发表于 2019-01-10 11:10 |显示全部楼层
本帖最后由 CDX0923 于 2019-01-10 11:12 编辑

回复 2# csccyab

论坛报错就多出现了几条回复

论坛徽章:
0
发表于 2019-01-10 14:01 |显示全部楼层
This should be correct:

awk -F',' 'FNR>1{a[$1,$2,$3,$4]} FILENAME==ARGV[1]&&FNR>1{a1[$1,$2,$3,$4]++} FILENAME==ARGV[2]&&FNR>1{a2[$1,$2,$3,$4]++} FILENAME==ARGV[3]&&FNR>1{a3[$1,$2,$3,$4]++}END{for (i in a) {split(i,b,SUBSEP); printf "%s,%s,%s,%s,%d,%d,%d\n",b[1],b[2],b[3],b[4],a1[i],a2[i],a3[i]}} ' file1 file2 file3

评分

参与人数 1信誉积分 +5 收起 理由
CDX0923 + 5 很给力! 如果是几十个文件的话,这个写法有.

查看全部评分

论坛徽章:
0
发表于 2019-01-10 17:29 |显示全部楼层
csccyab 发表于 2019-01-10 14:01
This should be correct:awk -F',' 'FNR>1{a[$1,$2,$3,$4]} FILENAME==ARGV[1]&&FNR>1{a1[$1,$2,$3,$4]++}  ...

可以了,谢谢大神

论坛徽章:
0
发表于 2019-01-11 10:27 |显示全部楼层
回复 6# csccyab

如果是几十个文件的话这个有优化的写法吗

论坛徽章:
0
发表于 2019-01-11 17:16 |显示全部楼层
本帖最后由 csccyab 于 2019-01-24 20:59 编辑

Python 版本

$ cat 3.py
import collections, sys, re

filecount=0
dict1 = collections.defaultdict(list)

for file1 in sys.argv[1:]:
   filecount+=1
   f = open(file1, "r")
   linecount=1
   for line in f:
      if linecount>1:
         p = re.search("^(.+),.+", line.strip())
         if p:
            dict1[p.group(1)].append(filecount)
      linecount+=1

for the_key, the_value in dict1.iteritems():
   count=''
   sys.stdout.write(the_key + ',')
   c = collections.Counter(the_value)
   for i in range(1,filecount+1):
      if count:
         count = count + "," + str(c)
      else:
         count = str(c)
   print(count)


$ python 3.py file1 file2 file3
亚洲,中国,辽宁,沈阳,1,1,0
亚洲,中国,陕西,西安,2,1,2
亚洲,中国,甘肃,兰州,0,0,1
亚洲,中国,河南,郑州,0,1,0
亚洲,中国,宁夏,银川,1,1,0
亚洲,中国,河北,石家庄,1,0,1


论坛徽章:
0
发表于 2019-01-24 15:06 |显示全部楼层
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <regex.h>
  4. #include <string.h>

  5. struct LinkedList {
  6.         int* count;
  7.         char* data;
  8.         struct LinkedList *next;
  9. };

  10. typedef struct LinkedList *node;

  11. int main(int argc, char *argv[]) {
  12.         int i;
  13.         FILE *f;
  14.         char line[30];
  15.         const char* pattern = "(.+),.+";
  16.         node head = NULL;
  17.         int linecount;
  18.         char firstline[30];

  19.         regex_t preg;
  20.         regmatch_t pmatch[50];
  21.         regcomp(&preg, pattern, REG_EXTENDED);


  22.         for (i=1; i<argc; i++) {
  23.                 f = fopen(argv, "r");
  24.                 linecount = 0;
  25.                 if (f == NULL){
  26.                         printf("Can't open file %s", argv);
  27.                         exit(1);
  28.                 }
  29.                 int r=0;
  30.                 while (fscanf(f, "%s", line) == 1) {
  31.                         linecount++;
  32.                         if (linecount > 1) {
  33.                                 if (!regexec(&preg, line, 3, pmatch, 0)) {
  34.                                         if (head == NULL){
  35.                                                 head = (node)malloc(sizeof(struct LinkedList));
  36.                                                 head->data = malloc(50);
  37.                                                 head->next = NULL;
  38.                                                 strncpy(head->data, line + pmatch[1].rm_so, pmatch[1].rm_eo - pmatch[1].rm_so);
  39.                                                 head->count = (int*)calloc(argc-1, sizeof(int));
  40.                                                 head->count[i-1]++;
  41.                                         } else {
  42.                                                 node temp, p;
  43.                                                 p = head;

  44.                                                 temp = (node)malloc(sizeof(struct LinkedList));
  45.                                                 temp->data = malloc(50);
  46.                                                 temp->next = NULL;
  47.                                                 temp->count = (int*)calloc(argc-1, sizeof(int));
  48.                                                 temp->count[i-1] = 1;
  49.                                                 strncpy(temp->data, line + pmatch[1].rm_so, pmatch[1].rm_eo - pmatch[1].rm_so);

  50.                                                 while(1){
  51.                                                         int res = strcmp(temp->data, p->data);
  52.                                                         if (res==0) {
  53.                                                                 p->count[i-1]++;
  54.                                                                 break;
  55.                                                         } else {
  56.                                                                 if (p->next == NULL) {
  57.                                                                         p->next = temp;
  58.                                                                         break;
  59.                                                                 }
  60.                                                         }
  61.                                                         p = p->next;
  62.                                                 }
  63.                                         }
  64.                                 }
  65.                         } else {
  66.                                 regexec(&preg, line, 3, pmatch, 0);
  67.                                 strncpy(firstline, line + pmatch[1].rm_so, pmatch[1].rm_eo - pmatch[1].rm_so);
  68.                         }
  69.                 }
  70.                 fclose(f);
  71.         }

  72.         node ptr = head;

  73.         printf("%s", firstline);
  74.         for (i=1; i<argc; i++)
  75.                 printf(",%s", argv);
  76.         printf("\n");

  77.         while (ptr != NULL){
  78.                 printf("%s", ptr->data);
  79.                 int j;
  80.                 for (j=0; j<argc-1; j++)
  81.                         printf(",%d", ptr->count[j]);
  82.                 printf("\n");
  83.                 ptr = ptr->next;
  84.         }
  85. }
复制代码


$ ./ll 1.txt 2.txt 3.txt
洲,国,省,市,1.txt,2.txt,3.txt
亚洲,中国,宁夏,银川,1,1,0
亚洲,中国,辽宁,沈阳,1,1,0
亚洲,中国,河北,石家庄,1,0,1
亚洲,中国,陕西,西安,2,1,2
亚洲,中国,河南,郑州,0,1,0
亚洲,中国,甘肃,兰州,0,0,1

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

基于案例的 SQL 优化实战训练营

讲师:中电福富特级专家梁敬彬,参与本次课程培训,你将收获:
1. 能编写出较为高效的 SQL;
2. 能解决70%以上的数据库常见优化问题;
3. 能得到老师提供的高效的相关工具和解决方案;
4. 能举一反三,收获不仅仅是 SQL 优化。
现在购票享受8.8折优惠!
----------------------------------------
优惠时间:2019年3月20日前

大会官网>>
  

北京盛拓优讯信息技术有限公司. 版权所有 16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122
中国互联网协会会员  联系我们:huangweiwei@it168.com
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP