A
A
avp2017-02-07 12:58:03
linux
avp, 2017-02-07 12:58:03

How to write a script in Bash?

We have input data
[Lots of data]
Mon, 1 Aug 2012 00:15:00 +0200|1.1.1.1|dnepr| - |user logged in| -
Mon, 1 Aug 2012 00:15:00 +0200|1.1.1.1|dnepr| - |user changed password| -
Mon, 1 Aug 2012 00:15:00 +0200|1.1.1.1|dnepr| - |user logged off| -
[Lots of data]
Need to find these three lines. The first line - the user is authorized, the second - the user has changed the password, the third - the user is logged out.
I only thought of filtering them out with awk
awk '/user logged in|user changed password|user logged off/ {print}' script.log
And I need to check that all three events with the same user dnepr, and also at the same second, are recorded in the log. I don't quite understand how I can use awk to check several lines at once and give the result - [dnepr] - bot is life

Answer the question

In order to leave comments, you need to log in

4 answer(s)
A
Alexander Shelemetiev, 2017-02-07
@zoroda

I don't have time to write an example script now. But the idea is this:
After awk processing, sort the result, then feed it to the next awk as input. In the second awk script, keep the previous date, username, and action values. Compare them with current ones. So you can catch records with the same time, user and full set of actions.
See awk's BEGIN section and the use of variables for more information.

A
Adamos, 2017-02-07
@Adamos

Regexps have such a thing as back reference. Allows you to create a regular expression with the substitution of already found values, such as (\d\d:\d\d:\d\d)[^:]*\[([^]]+)\] - \[user logged in\] [^:]+\1[^[]+\[\2\] - \[user changed password\].....

Y
Yuri Chudnovsky, 2017-02-07
@Frankenstine

It seems to me that it will be easiest for you to write a script based on reading a file line by line:
while read -r line
do
(here is the whole logic)
done < "/path/to/filename"
where in the logic you will use variables to track the presence of the necessary data in the lines .

A
abcd0x00, 2017-02-08
@abcd0x00

Through the state machine

text="\
abc1
abc2
Mon, 1 Aug 2012 00:15:00 +0200|1.1.1.1|dnepr1| - |user logged in| -
Mon, 1 Aug 2012 00:15:00 +0200|1.1.1.1|dnepr1| - |user changed password| -
Mon, 1 Aug 2012 00:15:00 +0200|1.1.1.1|dnepr1| - |user logged off| -
def1
def2
Mon, 1 Aug 2012 00:15:00 +xxxx|1.1.1.1|dnepr2| - |user logged in| -
Mon, 1 Aug 2012 00:15:00 +0200|1.1.1.1|dnepr2| - |user logged in| -
Mon, 1 Aug 2012 00:15:00 +0200|1.1.1.1|dnepr2| - |user changed password| -
Mon, 1 Aug 2012 00:15:00 +0200|1.1.1.1|dnepr2| - |user logged off| -
ghi1
ghi2
"

fsm()
{
    awk '{
        switch (state) {
        case 0:
            if (/user logged in/) {
                out = $0
                state = 1
            }
            break
        case 1:
            if (/user logged in/) {
                out = $0;
            } else if (/user changed password/) {
                out = out"\n"$0
                state = 2
            } else {
                out = ""
                state = 0
            }
            break
        case 2:
            if (/user logged off/) {
                out = out"\n"$0
                print out
                out = ""
                state = 0
            } else {
                out = ""
                state = 0
            }
            break
        }
    }'
}

echo "$text" | fsm

Conclusion
[[email protected] tmp]$ echo "$text" | fsm
Mon, 1 Aug 2012 00:15:00 +0200|1.1.1.1|dnepr1| - |user logged in| -
Mon, 1 Aug 2012 00:15:00 +0200|1.1.1.1|dnepr1| - |user changed password| -
Mon, 1 Aug 2012 00:15:00 +0200|1.1.1.1|dnepr1| - |user logged off| -
Mon, 1 Aug 2012 00:15:00 +0200|1.1.1.1|dnepr2| - |user logged in| -
Mon, 1 Aug 2012 00:15:00 +0200|1.1.1.1|dnepr2| - |user changed password| -
Mon, 1 Aug 2012 00:15:00 +0200|1.1.1.1|dnepr2| - |user logged off| -
[[email protected] tmp]$

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question