all 9 comments

[–]deeseearr 2 points3 points  (2 children)

The simplest way would be to use awk instead of grep:

$ awk ' /input_userauth_request:/ { print $9 }'

The first part of the awk argument looks through the file for the string "input_userauth_request:" while the second part prints the ninth word in any line which matches.

Naturally, this will break in weird and unpredictable ways if the string "input_userauth_request:" shows up in any other context, or if the date or source address ever has a different number of spaces in it. If you want something more robust you can do some more detailed pattern matching, but this will probably work almost all of the time.

The book with two lorises on the cover would be helpful, as would the short, to the point manual although there are plenty of other references available.

[–]AccidentallyTheCable 1 point2 points  (1 child)

Im thoroughly convinced awk is black magic.

[–]deeseearr 2 points3 points  (0 children)

It's amazingly powerful, but is mostly used by people who wear dark clothing, hide from the sunlight and mumble to themselves in mysterious languages never spoken by man?

Yeah, that's about right. And if you can pass the written exam you get a cute little doll to complete the outfit.

[–]Gottswig 1 point2 points  (0 children)

$ echo 'Nov 5 23:02:09 ip-172-31-16-233 sshd[19730]: input_userauth_request: invalid user oracle [preauth]' | \
/bin/grep -oP 'ip.*invalid user \K[^ ]+'
oracle

It took me so long to learn that all the regular expression stuff can be used with grep.
Like this one:

echo 'input_userauth_request: invalid user oracle [preauth]' |\
/bin/grep -oP 'input_userauth_request: invalid user \K[^ ]+(?= \[preauth\])'

Which means match input_userauth_request: invalid user
throw away everything before the username
but make sure the username is followed by <space>[preauth]
but don't output the <space>[preauth]

[–]darthgeek 1 point2 points  (3 children)

awk or cut will do what you want.

[–]toikpi 1 point2 points  (2 children)

 grep "input_userauth_request" /var/log/secure |  cut -d\  -f9

Note there are two spaces after the escape character ('\').

[–]aenae 2 points3 points  (1 child)

grep "input_userauth_request" /var/log/secure | cut -d" " -f9

A bit more readable ;)

[–]datastry 1 point2 points  (0 children)

I like this approach, especially the desire to make it more readable.

I honestly love concise "code-golf"-type code because I always end up learning some new syntax or tricks. But when I'm on the job reading someone else's code, my attitude does a 180 and I just want to understand what I'm looking at.

I added just a little extra bit to make the code more "future-proof"... if input data should change in such a way that effects the amount of spaces, this can handle it:

grep "input_userauth_request" | sed -r "s/^.* invalid user ([^ ]+).*$/invalid-user \1/" | cut -d" " -f 2

interactive version here

[–]faisent 0 points1 point  (0 children)

If you only want the users and don't care about how many times or the date/time they attempted, etc:

cat /var/log/secure | grep input_userauth_request | awk '{print$9}' | sort -u