sed 或 awk 将两个文件与 sum 组合
Posted
技术标签:
【中文标题】sed 或 awk 将两个文件与 sum 组合【英文标题】:sed or awk combining two files with sum 【发布时间】:2015-08-01 13:25:41 【问题描述】:我们有脚本可以从 squid access.log 中删除除域名之外的所有内容,并报告每个 URL 的总命中数,我有一个生成的两个文件,一个有缓存命中,另一个有缓存未命中,我正在寻找一种方法来组合这些文件如下 -
cat TCP_MISS_data.txt
Domains CacheMiss
abc.com 21
def.com 38
xyz.com 12
cat TCP_HITS_data.txt
Domains CacheHits
def.com 28
abc.com 10
xyz.com
cat Combined_data.txt
Domains CacheMiss CacheHits TotalHits
abc.com 21 10 31
def.com 38 28 66
xyz.com 12 0 12
感谢任何帮助。
更新:
我使用下面的 awk 单行从访问日志中删除域和命中,它输出一个包含所有域及其命中的文件,而不管 HITS 和 MISSES。
猫访问.log | awk '打印 $7' | awk '!/^http/sub(/^/,"http://")1' | awk -F"/" '打印 $3' | awk -F":" '打印 $1' | awk -F"。" 'f1=NF;f2=NF-1;打印 $f2 "." $f1' |排序 |唯一的-c |排序 -n为了区分我在下面所做的命中和未命中 -
猫访问.log | grep TCP_MISS | awk '打印 $7' | awk '!/^http/sub(/^/,"http://")1' | awk -F"/" '打印 $3' | awk -F":" '打印 $1' | awk -F"。" 'f1=NF;f2=NF-1;打印 $f2 "." $f1' |排序 |唯一的-c |排序 -n > TCP_MISS_data 猫访问.log | grep TCP_HIT | awk '打印 $7' | awk '!/^http/sub(/^/,"http://")1' | awk -F"/" '打印 $3' | awk -F":" '打印 $1' | awk -F"。" 'f1=NF;f2=NF-1;打印 $f2 "." $f1' |排序 |唯一的-c |排序 -n > TCP_HITS_data现在我得到了两个文件,TCP_MISS_data 和 TCP_HITS_data,它们的行不相等,我尝试按照我上面的帖子中的说明合并这两个文件。
【问题讨论】:
你被困在哪里了? Tom 我仍然是 awk 的新手,但我会尝试完成 Kent 的一个班轮。谢谢。 新手并没有错,您只需要在您的问题中表现出一些研究成果。如果您自己尝试过某些东西但它不起作用,请edit 您的问题向我们展示。否则不清楚你的问题到底出在哪里,看起来你只是想让别人为你写一些代码。 【参考方案1】:这个oneliner可以完成这项工作:
awk 'NR==FNRa[$1]=$2;next
$1 in aprintf "%s %s %s %s\n", $1,a[$1],($2?$2:0),(FNR>1?a[$1]+$2:"TotalHits")' missFile hitFile
要获得“漂亮”的输出格式,您可以调整printf
格式,或者像awk ..... |column -t
一样将结果通过管道传输到column -t
使用您的示例输入:
kent$ head f*
==> f1 <==
Domains CacheMiss
abc.com 21
def.com 38
xyz.com 12
==> f2 <==
Domains CacheHits
def.com 28
abc.com 10
xyz.com
kent$ awk 'NR==FNRa[$1]=$2;next$1 in aprintf "%s %s %s %s\n", $1,a[$1],($2?$2:0),(FNR>1?a[$1]+$2:"TotalHits")' f1 f2|column -t
Domains CacheMiss CacheHits TotalHits
def.com 38 28 66
abc.com 21 10 31
xyz.com 12 0 12
编辑:
添加一些解释:
awk 'NR==FNRa[$1]=$2;next #process the first file, store in a hashtable, key:col1, value:col2
$1 in a #starting processing 2nd file, if file2.col1 in hashtable, do followings:
printf "%s %s %s %s\n", $1,a[$1], #printf output with format
($2?$2:0), #if file2.cols was empty, we take it as 0
(FNR>1?a[$1]+$2:"TotalHits") #if first line, we dont do sum, print "totalHits" text
' f1 f2 #two input files
【讨论】:
解释一下你的脚本会很有用,希望下次OP遇到任何问题时,他们的第一个想法是让其他人在这里为他们解决。 @TomFenech 好的,我添加了一些描述,尽管我认为代码足够简单。 感谢 Kent 的回复,您提供的脚本仅适用于 5 行,即如果 f2 有 5 行而 f1 有 100 行,则其匹配值仅适用于 f1 中的 5 个域。我需要获取 f1 中所有 100 行的命中和未命中,如果域不存在 f1,它可以在 TotalHits 中显示 0 吗?再次感谢。 您应该在问题中提出这些要求。尝试DIY一下,我已经完成了:“if some key in hashtable”的部分,你可以试试else
部分。以上是关于sed 或 awk 将两个文件与 sum 组合的主要内容,如果未能解决你的问题,请参考以下文章
如何在两个模式之间打印线,包括或不包括(在 sed、AWK 或 Perl 中)?
如何在两个模式之间打印线,包括或不包括(在 sed、AWK 或 Perl 中)?