【发布时间】:2013-02-14 14:06:08
【问题描述】:
我一直在用awk总结多个文件,这个是用来总结服务器日志解析值的总结,确实加快了最终的整体计数但是我遇到了一个小问题和我的典型例子在网络上点击并没有帮助。
示例如下:
cat file1
aa 1
bb 2
cc 3
ee 4
cat file2
aa 1
bb 2
cc 3
dd 4
cat file3
aa 1
bb 2
cc 3
ff 4
还有脚本:
cat test.sh
#!/bin/bash
files="file1 file2 file3"
i=0;
oldname="";
for names in $(echo $files); do
((i++));
if [ $i == 1 ]; then
oldname=$names
#echo "-- $i $names"
shift;
else
oldname1=$names.$$
awk 'NR==FNR { _[$1]=$2 } NR!=FNR { if(_[$1] != "") nn=0; nn=($2+_[$1]); print $1" "nn }' $names $oldname> $oldname1
if [ $i -gt 2 ]; then
rm $oldname;
fi
oldname=$oldname1
fi
done
echo "------------------------------ $i"
cat $oldname
当我运行它时,相同的列会被添加,但那些只出现在其中一个文件中的列不会
./test.sh
------------------------------ 3
aa 3
bb 6
cc 9
ee 4
ff dd 没有出现在列表中,据我在 NR==FR 中看到的
我遇到过这个:
http://dbaspot.com/shell/246751-awk-comparing-two-files-problem.html
you want all the lines in file1 that are not in file2,
awk 'NR == FNR { a[$0]; next } !($0 in a)' file2 file1
If you want only uniq lines in file1 that are not in file2,
awk 'NR == FNR { a[$0]; next } !($0 in a) { print; a[$0] }'
file2
file1
但这只会在尝试时使当前问题进一步复杂化,因为许多其他字段会重复
发布问题后 - 更新内容……和测试……
我想坚持使用 awk,因为它似乎是一种更短的实现结果的方法,但仍然存在问题..
awk '{a[$1]+=$2}END{for (k in a) print k,a[k]}' file1 file2 file3
aa 3
bb 6
cc 9
ee 4
ff 4
gg 4
RESULT_SET_4 0
RESULT_SET_3 0
RESULT_SET_2 0
RESULT_SET_1 0
$ cat file1
RESULT_SET_1
aa 1
RESULT_SET_2
bb 2
RESULT_SET_3
cc 3
RESULT_SET_4
ff 4
$ cat file2
RESULT_SET_1
aa 1
RESULT_SET_2
bb 2
RESULT_SET_3
cc 3
RESULT_SET_4
ee 4
文件内容没有原样保留,即结果不在标题下,我原来的方法确实保持原样
更新的预期输出 - 正确上下文中的标题
cat file1
RESULT_SET_1
aa 1
RESULT_SET_2
bb 2
RESULT_SET_3
cc 3
RESULT_SET_4
ff 4
cat file2
RESULT_SET_1
aa 1
RESULT_SET_2
bb 2
RESULT_SET_3
cc 3
RESULT_SET_4
ee 4
cat file3
RESULT_SET_1
aa 1
RESULT_SET_2
bb 2
RESULT_SET_3
cc 3
RESULT_SET_4
gg 4
test.sh awk line to produce above is :
awk -v i=$i 'NR==FNR { _[$1]=$2 } NR!=FNR { if (_[$1] != "") { if ($2 ~ /[0-9]/) { nn=($2+_[$1]); print $1" "nn; } else { print;} }else { print; } }' $names $oldname> $oldname1
./test.sh
------------------------------ 3
RESULT_SET_1
aa 3
RESULT_SET_2
bb 6
RESULT_SET_3
cc 9
RESULT_SET_4
ff 4
有效但破坏了所需的格式
awk '($2 != "") {a[$1]+=$2}; ($2 == "") { a[$1]=$2 } END {for (k in a) print k,a[k]} ' file1 file2 file3
aa 3
bb 6
cc 9
ee 4
ff 4
gg 4
RESULT_SET_4
RESULT_SET_3
RESULT_SET_2
RESULT_SET_1
【问题讨论】:
-
什么是“标题”?在您首次发布的示例数据中,我没有看到类似的内容。这使它成为一个不同的问题。如果您在问题被回答后如此显着地更改问题,您可能不应该期望人们再次回答它。
-
是的,对不起 :) 我的错,报告确实有标题然后字段值我应该重新发布一个新问题吗?
-
现在的预期输出是什么?
-
用预期的输出更新了问题,基本上每个服务器输出都会有每个段的标题,后跟字段及其值......有点像 file1 file2 的最后更新内容,并且产生了预期的结果通过原始脚本 - 明显的问题仍然存在 - 下面的过程确实有效,但顺序丢失并且标题以不正确的格式显示
-
我认为这对其他人非常有用,只要他们首先以不同的方式考虑日志。所以我把它作为一个项目在这里github.com/vahidhedayati/summarise-server-logs
标签: linux bash shell sorting awk