![](/img/trans.png)
[英]Read and run different command based on each line of file in Bash Linux?
[英]Linux Bash Shell read log file compare each line to the reset of the file
我有这个很大的身份验证日志文件。 我已经将它与SED和AWK命令所需的信息进行了配对。 现在,我需要配对用户何时连接以及何时与服务器断开连接,以记录用户登录的时间和时间。
用户登录时,在日志中可以看到其用户名和IP端口。 当他们注销时,您可以看到有IP端口。 因此,我需要匹配这些IP端口,然后从它们连接的线路中吐出信息。
Date,time,Username,Viewer,IPPort <br>
20180911,12:00,Chris,New,55567 <br>
20180911,12:30,Tom,New,55577 <<<<<-Connections <br>
20180911,12:45,Larry,New,55587 <br>
20180911,14:00,,,55567 <br>
20180911,15:30,,,55577 <<<<<-When user logs off <br>
20180911,16:45,,,55587 <br>
我首先想到的是使用嵌套的while循环。 因此,转到每一行,然后在该行上再次遍历每一行以找到匹配项。 确实会遍历文件并匹配内容,但是会在嵌套循环中针对自身重新检查顶行。 必须有一种更清洁的方式来完成此任务。
这就是我的循环当前的样子。
INPUT=firstreport.csv
OLDIFS=$IFS
IFS=,
[ ! -f $INPUT ] && { echo "$INPUT file not found"; exit 99; }
while read Date Time Username Viewer IP
do
echo "IP : $IP"
IPCHECK=$IP
while read Date Time Username Viewer IP
do
if [[ $IPCHECK == $IP ]]; then
echo "Match : $IP"
fi
done < $INPUT
done < $INPUT
IFS=$OLDIFS`
我将如何完成这项工作的任何建议将不胜感激。 我的最终目标是拥有一份报告,可以将其转储到excel中并显示用户活动图。
谢谢克里斯
鉴于已记录的端口是相当唯一的,并且如注释中所述,它们始终记录在第5列中,因此您应该能够使用以下sort
命令按端口对条目进行分组,从而重新组合有关用户连接的所有信息:
sort -t, -k 5,5
在此sort
命令中,我们使用-t,
选项指定字段之间用逗号分隔,然后使用-k 5,5
要求sort
仅对第5个字段进行排序。
(注意:我建议在注释中使用-k 5.1
,这意味着从第5个字段的第一个字符开始排序,但是1) .x
字符偏移量默认为字段的第一个/最后一个字符作为开始/结束位置,并且可以是省略)2)您的字段可能比摘录中的字段多,如果未指定end字段,则不必要在排序中使用该字段)
固定应用于样本输入,使端口成为注销条目中的第5个字段:
20180911,12:00,Chris,New,55567
20180911,12:30,Tom,New,55577
20180911,12:45,Larry,New,55587
20180911,14:00,,,55567
20180911,15:30,,,55577
20180911,16:45,,,55587
它产生以下输出:
20180911,12:00,Chris,New,55567
20180911,14:00,,,55567
20180911,12:30,Tom,New,55577
20180911,15:30,,,55577
20180911,12:45,Larry,New,55587
20180911,16:45,,,55587
您可以在这里尝试 。
这是GNU awk:
gawk '
BEGIN { FS = OFS = "," }
NR == 1 {next}
$3 != "" { # connection
conn[$5]["on"] = $3 FS $4 FS $1 FS $2
}
$3 == "" {
if ($5 in conn) {
conn[$5]["off"] = $1 FS $2
}
else {
print "Error: found a log off with no log on, line " NR
}
}
END {
print "IPPort","User","Viewer","ON date","ON time","OFF date","OFF time"
for (id in conn) {
print id, conn[id]["on"], conn[id]["off"]
}
}
' file
IPPort,User,Viewer,ON date,ON time,OFF date,OFF time
55567,Chris,New,20180911,12:00,20180911,14:00
55577,Tom,New,20180911,12:30,20180911,15:30
55587,Larry,New,20180911,12:45,20180911,16:45
适用于年龄较大的awks(已通过mawk测试)
awk '
BEGIN { FS = OFS = "," }
NR == 1 {next}
$3 != "" { ids[$5]; conn[$5,"on"] = $3 FS $4 FS $1 FS $2 }
$3 == "" {
if ($5 in ids)
conn[$5,"off"] = $1 FS $2
else
print "Error: found a log off with no log on, line " NR
}
END {
print "IPPort","User","Viewer","ON date","ON time","OFF date","OFF time"
for (id in ids)
print id, conn[id,"on"], conn[id,"off"]
}
' file
以此替换内部循环:
line=0
while read Date Time Username Viewer IP COMMENT
do
let line=1+$line
awk -F "$IFS" '
BEGIN {
IP="'${IP}'"
if(!match(IP, "^[0-9]+$")) {exit}
line='"${line}"'
}
NR<line { next }
NR==line {
print "CONNECT:",$0
next
}
$5==IP && $4 != "New" {
print "DISCONNECT:", $0
exit
}
$5==IP {
print "FOUND RECONNECT BEFORE DISCONNECT"
exit
}
' $INPUT
done < $INPUT
并稍微更改输入,如下所示:
20180911,12:00,Chris,New,55567,
20180911,12:30,Tom,New,55577, <<<<<-Connections
20180911,12:45,Larry,New,55587,
20180911,14:00,,55567,
20180911,15:30,,55577, <<<<<-When user logs off
20180911,16:45,,55587,
20180911,16:45,Tom,New,55577, <<<<<-reconnect
20180911,16:45,55577, <<<<<-redisconnect
20180911,16:45,CURLY,New,55577, <<<<<-reconnect
20180911,16:45,MOE,New,55577, <<<<<- foobar
20180911,16:45,55577, <<<<<-redisconnect
给出以下内容:
CONNECT: 20180911,12:00,Chris,New,55567,
DISCONNECT: 20180911,14:00,,55567,
CONNECT: 20180911,12:30,Tom,New,55577, <<<<<-Connections
DISCONNECT: 20180911,15:30,,55577, <<<<<-When user logs off
CONNECT: 20180911,12:45,Larry,New,55587,
DISCONNECT: 20180911,16:45,,55587,
CONNECT: 20180911,16:45,Tom,New,55577, <<<<<-reconnect
FOUND RECONNECT BEFORE DISCONNECT
CONNECT: 20180911,16:45,CURLY,New,55577, <<<<<-reconnect
FOUND RECONNECT BEFORE DISCONNECT
CONNECT: 20180911,16:45,MOE,New,55577, <<<<<- foobar
我想这就是你想要的。 我怀疑在您的真实数据上,您将需要添加更多条件以确保用户和端口有意义。
精巧的方法是在python或perl中执行此操作(整个脚本),并使用前瞻性的多行正则表达式。
****请注意, awk
脚本已更新,但输入/输出仍然是原始的
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.