我有一个日志文件,我需要获取指定的输出,我需要逻辑写入shell脚本

时间:2017-02-13 04:08:28

标签: linux bash shell unix awk

以下是日志文件和预期输出。文件输出应具有已下载的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

4 个答案:

答案 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处理所有行后执行,在这种情况下打印mapRead 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