我的日志文件至少有100G。 日志文件目录结构如下:
drwxrwxr-x 2 griyn griyn 4096 Jul 2 14:33 lcdc-0615-00.log
drwxrwxr-x 2 griyn griyn 4096 Jun 29 14:22 lcdc-0615-01.log
drwxrwxr-x 2 griyn griyn 4096 Jun 28 21:25 lcdc-0615-02.log
drwxrwxr-x 2 griyn griyn 4096 Jun 28 21:25 lcdc-0615-03.log
drwxrwxr-x 2 griyn griyn 4096 Jun 28 21:25 lcdc-0615-04.log
drwxrwxr-x 2 griyn griyn 4096 Jun 28 21:25 lcdc-0615-05.log
drwxrwxr-x 2 griyn griyn 4096 Jun 28 21:25 lcdc-0615-06.log
在每个目录中,
[griyn@cp01-vm-griyn test_data]$ cd lcdc-0615-00.log/
[griyn@cp01-vm-griyn lcdc-0615-00.log]$ ll
total 361216
-rw-rw-r-- 1 griyn griyn 184936785 Jun 28 21:19 yq01-spi-mx0.yq01
-rw-rw-r-- 1 griyn griyn 184936680 Jun 28 21:20 yq01-spi-mx22.yq01
在此处记录文件内容
1 peer_addr[yq01-spi-mx38:29129]
2 peer_addr[yq01-spi-mx38:29129]
3 peer_addr[yq01-ps-beehive-agent3677:29082]
4 peer_addr[yq01-spi-mx38:29129]
5 peer_addr[yq01-spi-mx38:29129]
6 peer_addr[yq01-spi-mx38:29129]
7 peer_addr[yq01-ps-beehive-agent3677:29082]
8 peer_addr[yq01-spi-mx38:29129]
9 peer_addr[yq01-spi-mx38:29129]
10 peer_addr[yq01-ps-beehive-agent3677:29082]
11 peer_addr[yq01-spi-mx38:29129]
12 peer_addr[yq01-ps-beehive-agent3677:29082]
13 peer_addr[yq01-spi-mx38:29129]
14 peer_addr[yq01-ps-beehive-agent3677:29082]
15 peer_addr[yq01-spi-mx38:29129]
16 peer_addr[yq01-spi-mx38:29129]
17 peer_addr[yq01-ps-beehive-agent3677:29082]
18 peer_addr[yq01-spi-mx38:29129]
19 peer_addr[yq01-spi-mx38:29129]
20 peer_addr[yq01-ps-beehive-agent3677:29082]
21 peer_addr[yq01-spi-mx38:29129]
22 peer_addr[yq01-ps-beehive-agent3677:29082]
23 peer_addr[yq01-spi-mx38:29129]
我想通过shell脚本计算多个日志文件中机器名称的频率。 我这样使用AWK:
awk -F'[]:[]' '/peer_addr/{map[$2]+=1} END{for(key in map) {sum+=map[key];printf("%-15s %s\n", key, map[key]);} print "sum:",sum}' ${log_file_dir}/${log_path} >> ./conclusion/sum.log &
显然,我们需要一个地图结构来保存和更新结果。然后我有一个问题,就是AWK中的地图结构仅用于自已AWK。我无法将结果汇总到多个日志文件中。
我的临时解决方案是,使用AWK将每个日志文件的结果输出到一个文件,然后在该文件旁边再次使用AWK求和。
您有更有效的方法吗?
答案 0 :(得分:2)
如果文件数量很多,比允许的最大参数列表大得多,则可以通过以下方式使用Awk:
使用您要处理的所有文件创建文件。
$ find <logroot> -type f -iname '*.yq01' > <logroot>/logfiles.txt
使用awk自己创建ARGV
列表:
$ awk -F'[]:[]' '(NR==FNR){ARGV[ARGC++]=$0; next}
/peer_addr/{map[$2]++}
END{ for(key in map) {
sum+=map[key];
printf("%-15s %s\n", key, map[key]);
}
print "sum:",sum }
' <logroot>/logfiles.txt
ARGC
:ARGV
数组中的元素数。
ARGV
::一组命令行参数,不包括选项和程序参数,从零到ARGC-1
编号。ARGV
中的参数可以修改或添加;ARGC
可以更改。在每个输入文件结束时,awk会将ARGV
的下一个非null元素视为ARGC-1
的当前值(包括该值),下一个输入文件的名称。因此,将ARGV
的元素设置为null意味着不应将其视为输入文件。名称'-'
表示标准输入。如果参数与赋值操作数的格式匹配,则应将该参数视为赋值,而不是文件参数。
并行处理:
如果您想进行一些并行处理,您可能会对GNU parallel感兴趣:
$ cat <logroot>/logfiles.txt \
| parallel --jobs 4 ./process_files.sh \
| awk '{map[$1]+=$2}
END{ for(key in map) {
sum+=map[key];
printf("%-15s %s\n", key, map[key]);
}
print "sum:",sum
}'
与process_files.sh
:
#!/usr/bin/env bash
awk -F'[]:[]' '(NR==FNR){ARGV[ARGC++]=$0; next}
/peer_addr/{map[$2]++}
END{ for(key in map) {
sum+=map[key];
printf("%-15s %s\n", key, map[key]);
}}' "$@"