繁体   English   中英

Linux Bash Shell读取日志文件将每一行与该文件的重置进行比较

[英]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(已通过测试)

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM