不确定如何提出这个问题,因此我不知道如何在Google或SO上搜索它。让我告诉你给定的数据。顺便说一句,这只是一个Awk练习,它不是功课。一直试图解决这个问题2天。以下是一个例子;
Mon Sep 15 12:17:46 1997
User-Name = "wynng"
NAS-Identifier = 207.238.228.11
NAS-Port = 20104
Acct-Status-Type = Start
Acct-Delay-Time = 0
Acct-Session-Id = "239736724"
Acct-Authentic = RADIUS
Client-Port-DNIS = "3571800"
Framed-Protocol = PPP
Framed-Address = 207.238.228.57
Mon Sep 15 12:19:40 1997
User-Name = "wynng"
NAS-Identifier = 207.238.228.11
NAS-Port = 20104
Acct-Status-Type = Stop
Acct-Delay-Time = 0
Acct-Session-Id = "239736724"
Acct-Authentic = RADIUS
Acct-Session-Time = 115
Acct-Input-Octets = 3915
Acct-Output-Octets = 3315
Acct-Input-Packets = 83
Acct-Output-Packets = 66
Ascend-Disconnect-Cause = 45
Ascend-Connect-Progress = 60
Ascend-Data-Rate = 28800
Ascend-PreSession-Time = 40
Ascend-Pre-Input-Octets = 395
Ascend-Pre-Output-Octets = 347
Ascend-Pre-Input-Packets = 10
Ascend-Pre-Output-Packets = 11
Ascend-First-Dest = 207.238.228.255
Client-Port-DNIS = "3571800"
Framed-Protocol = PPP
Framed-Address = 207.238.228.57
因此日志文件包含各种用户的上述数据。我特意粘贴这个以显示该用户有登录,Acct-Status-Type = Start和注销,Acct-Status-Type = Stop。这算作一个会话。因此,我需要生成以下输出。
User: "wynng"
Number of Sessions: 1
Total Connect Time: 115
Input Bandwidth Usage: 83
Output Bandwidth Usage: 66
我遇到的问题是保持信息以某种方式附加到用户身上。当会话处于停止状态时,日志文件中的每个条目都具有相同的信息,因此我只能使用正则表达式
/ Acct-Input-Packets / {inPackets = $ 3}
/ Acct-Output-Packets / {outPackets = $ 3}
每次迭代数据都会覆盖过去的值。 我想要做的是,如果我找到一个用户名条目并且此条目有一个停止,那么我想为该用户记录输入/输出数据包值。这是我难倒的地方。
对于会话值,我考虑将用户名保存在一个数组中,然后在END {}中计算重复项,并除以2,如果是偶数则大于2。如果奇数然后除以2然后将它放下。
我不一定想得到答案,但也许是一些提示/指导,或者也许是一个我可以扩展的简单例子。
答案 0 :(得分:1)
您可以查看以下各行:
/\w+\s\w+\s[0-9]{2}\s[0-9]{2}:[0-9]{2}:[0-9]{2}\s[0-9]{4}/
/User-Name\s+=\s+\"\w+\"/
/Acct-Status-Type\s+=\s+\w+/
/Acct-Input-Packets\s+=\s[0-9]+/
/Acct-Output-Packets\s+=\s[0-9]+/
/^$/
一旦你定义了你想要的东西(上面的模式),它只是条件的问题,并将所有这些数据存储在某个数组中。
在下面的示例中,我将上面的每个值类型存储在每个类型的专用数组中,其中count
索引在检测到空行/^$/
时递增:
awk 'BEGIN{
count = 1;
i = 1;
}{
if ($0 ~ /\w+\s\w+\s[0-9]{2}\s[0-9]{2}:[0-9]{2}:[0-9]{2}\s[0-9]{4}/){
match($0, /\w+\s(\w+)\s([0-9]{2})\s([0-9]{2}):([0-9]{2}):([0-9]{2})\s([0-9]{4})/, n);
match("JanFebMarAprMayJunJulAugSepOctNovDec",n[1])
n[1] = sprintf("%02d",(RSTART+2)/3);
arr[count]=mktime(n[6] " " n[1] " " n[2] " " n[3] " " n[4] " " n[5]);
order[i]=count;
i++;
}
else if ($0 ~ /User-Name\s+=\s+\"\w+\"/){
match($0, /User-Name\s+=\s+\"(\w+)\"/, n);
name[count]=n[1];
}
else if ($0 ~ /Acct-Status-Type\s+=\s+\w+/){
match($0, /Acct-Status-Type\s+=\s+(\w+)/, n);
status[count]=n[1];
}
else if ($0 ~ /^$/){
count++;
}
else if ($0 ~ /Acct-Input-Packets\s+=\s[0-9]+/){
match($0, /Acct-Input-Packets\s+=\s([0-9]+)/, n);
input[count]=n[1];
}
else if ($0 ~ /Acct-Output-Packets\s+=\s[0-9]+/){
match($0, /Acct-Output-Packets\s+=\s([0-9]+)/, n);
output[count]=n[1];
}
}
END{
for (i = 1; i <= length(order); i++) {
val = name[order[i]];
if (length(user[val]) == 0) {
valueStart = "0";
if (status[order[i]] == "Start"){
valueStart = arr[order[i]];
}
user[val]= valueStart "|0|0|0|0";
}
else {
split(user[val], nameArr, "|");
if (status[order[i]]=="Stop"){
nameArr[2]++;
nameArr[3]+=arr[order[i]]-nameArr[1]
}
else if (status[order[i]] == "Start"){
# store date start
nameArr[1] = arr[order[i]];
}
nameArr[4]+=input[order[i]];
nameArr[5]+=output[order[i]];
user[val]= nameArr[1] "|" nameArr[2] "|" nameArr[3] "|" nameArr[4] "|" nameArr[5];
}
}
for (usr in user) {
split(user[usr], usrArr, "|");
print "User: " usr;
print "Number of Sessions: " usrArr[2];
print "Total Connect Time: " usrArr[3];
print "Input Bandwidth Usage: " usrArr[4];
print "Output Bandwidth Usage: " usrArr[5];
print "------------------------";
}
}' test.txt
使用match
函数提取值,如:
match($0, /User-Name\s+=\s+\"(\w+)\"/, n);
对于日期,我们必须解析月份字符串部分,我已经使用this post中的解决方案来提取:
match($0, /\w+\s(\w+)\s([0-9]{2})\s([0-9]{2}):([0-9]{2}):([0-9]{2})\s([0-9]{4})/, n);
match("JanFebMarAprMayJunJulAugSepOctNovDec",n[1])
n[1] = sprintf("%02d",(RSTART+2)/3);
收集值的所有处理都在END
子句中完成,我们必须对值进行分组,我创建一个user
数组,其中username
为关键值,值为a由|
分隔的所有不同类型的串联:
[startDate] "|" [sessionNum] "|" [connectionTime] "|" [inputUsage] "|" [outputUsage]
使用this data input(您的数据已扩展),它会给出:
User: TOTO
Number of Sessions: 1
Total Connect Time: 114
Input Bandwidth Usage: 83
Output Bandwidth Usage: 66
------------------------
User: wynng
Number of Sessions: 2
Total Connect Time: 228
Input Bandwidth Usage: 166
Output Bandwidth Usage: 132
------------------------