以下是日志文件和预期输出。文件输出应具有已下载的CustomerName和Size。有一个CustomerName:John已经下载了两次,所以在最终输出中我需要得到他下载的总大小。我需要帮助编写一个shell脚本。
谢谢
01-01-2012 01:13:36 Blah blah : blah CustomerName:Sam downloaded Blah Size:5432 bytes Carrier:Company-A
01-01-2012 01:13:45 Blah blah : blah CustomerName:John downloaded Blah Size:38655 bytes Carrier:Company-S
01-01-2012 01:13:47 Blah blah : blah CustomerName:Dave downloaded Blah Size:25632 bytes Carrier:Company-A
01-01-2012 01:13:50 Blah blah : blah CustomerName:John downloaded Blah Size:7213 bytes Carrier:Company-S
01-01-2012 01:13:58 Blah blah : blah CustomerName:Kristy downloaded Blah Size:70100 bytes Carrier:Company-V
预期输出
CustomerName: Sam Size: 5432
CustomerName: John Size: 45868
CustomerName: Dave Size: 25632
CustomerName: Kristy Size: 70100
答案 0 :(得分:2)
试试这个 -
awk -F '[ :]' '{name[$11]++ ; size[$11]+=$15} END \
{for (i in name) print "CustomerName: ", i, "Size:" size[i]}' test
其中test
是输入文件的名称。
输出 -
CustomerName: Dave Size:25632
CustomerName: John Size:45868
CustomerName: Sam Size:5432
CustomerName: Kristy Size:70100
解释 -
-F '[ :]'
将分隔符设置为space
和:
。因此,列的编号不同。
我定义了两个数组。数组name
包含不同人的名字。
数组size
包含基于人名的键,但包含下载的大小。
在END
之后的部分中,我将遍历name
数组中的名称并简单地获取名称和大小的值。我还根据您的问题在print
部分添加了一些文字。
答案 1 :(得分:0)
$cat xxx.txt | awk -F ":" '{print $5" "$6}' | awk '{print $1" "$5}' | awk '{arr[$1]+=$2} END {for (i in arr) {print i,arr[i]}}'
Dave 25632
John 45868
Sam 5432
Kristy 70100
其中xxx.txt
是输入文件
关于awk '{arr[$1]+=$2} END {for (i in arr) {print i,arr[i]}}'
的说明:
{arr[$1]+=$2}
将创建一个map
,其名称为键,数字为值,如果存在特定键,则将该数字添加到值中,END
块将为在awk
处理所有行后执行,在这种情况下打印map
。 Read more about the END block
答案 2 :(得分:0)
cat InputFile |awk -F'blah' '{print $3}'|awk -F'downloaded Blah' '{print $1 $2}'|awk -F'bytes' '{print $1}'|awk '{print $1" "$2}'|sed 's/:/\ :\ /g'
或
`#!/bin/bash
cat $1 |\ # $1 is input file name from command line.
awk -F'blah' '{print $3}'|\
awk -F'downloaded Blah' '{print $1 $2}'|\ #
awk -F'bytes' '{print $1}'|\
awk '{print $1" "$2}'|\
sed 's/:/\ :\ /g'`
两者都是一样的,只有一个用单行格式编写,第二个你可以把它保存为脚本,你可以稍后修改并更好地理解。
在awk中,-F
是用于剪切字符串的分隔符,这使得它更容易理解并轻松获得输出。正如你所提到的,你需要:
之前和之后的空格,我已经使用了sed。两者都会给出如下输出:
CustomerName : Sam Size : 5432
CustomerName : John Size : 38655
CustomerName : Dave Size : 25632
CustomerName : John Size : 7213
CustomerName : Kristy Size : 70100
答案 3 :(得分:0)
使用gsub
清除$10
中的非数字:
$ awk '
{
gsub(/[^0-9]/,"",$10) # remove non-digits
a[$7]+=$10 # count the sizes grouping on the name
}
END { # in the end
for(i in a)
print i, "Size:" a[i] # output
}' file
CustomerName:John Size:45868
CustomerName:Sam Size:5432
CustomerName:Kristy Size:70100
CustomerName:Dave Size:25632