Shell Regexp fiction

Hello,

Trying to get IP addresses from auth.log file,

Don't understand why this pattern is no valid
grep -o "/(\d+\.){3}\d+/g" /var/log/auth.log
What is the correct command to print each ip in such statement?
grep "Failed password" /var/log/auth.log | grep '(\d+\.){3}\d+'

Thanks
 
If the IP address you are looking for is always the Nth word, say the 9th, then I would suggest awk:

awk '/Failed password/ {print $9}' /var/log/auth.log

Your grep does not work because you seem to use perl patterns and extended regexen.
The extended regex for an IP address is grepped with grep -E '([0-9]+\.){3}[0-9]+'
 
Not sure, but you can fall back to a more basic pattern to get something working and then adjust one thing at a time to move toward what you want.

grep "Disconnected" /var/log/auth.log | grep -Eo '([0-9]+\.[0-9]+\.[0-9]+\.[0-9])' | sort | uniq
 
The FreeBSD version of grep(1) doesn't support pcre(1). Here's a quote from the 12.3 manual page
-P, --perl-regexp
Interpret PATTERN as a Perl regular expression. This option is
not supported in FreeBSD.

Instead you can use re_format(7)
`[0-9]' in ASCII matches any decimal digit.
OR

[[:digit:]]

Within a bracket expression, the name of a character class enclosed in
`[:' and `:]' stands for the list of all characters belonging to that
class. Standard character class names are:

alnum digit punct
alpha graph space
blank lower upper
cntrl print xdigit
 
Ended up with grep "Failed password" /var/log/auth.log | grep -oE '([0-9]+\.){3}[0-9]+' | uniq | wc -l 59
 
Ended up with grep "Failed password" /var/log/auth.log | grep -oE '([0-9]+\.){3}[0-9]+' | uniq | wc -l 59
That number (59) is likely not what you think it is. It's neither the total number of Failed password lines with IP addresses, nor the number of unique host IP addresses causing Failed password (since the sort is missing).

Note that grep | grep is a coding anti-pattern, something that's commonly seen, but that's substellar, and can easily be replaced with a better alternative. Why not use a single grep and save a process or three today? They are expensive beasts. If you show me two lines of your auth.log I'll come up with an awk(1) one-liner replacing also uniq and wc -l. In fact, I already started: :)

Bash:
$ cat auth.log
11:00 Failed password blah blah 1.2.3.4
12:00 Failed password blah blah 1.2.3.4 again!
13:00 Failed password blah blah 9.0.0.0
14:00 Good password, yay
15:00 Failed password blah blah 9.0.0.0 again!
16:00 Failed password blah blah 9.0.0.0 again!
17:00 Tired of logging
$ awk '/Failed password/ {print $6}' auth.log
1.2.3.4
1.2.3.4
9.0.0.0
9.0.0.0
9.0.0.0
$ awk '/Failed password/ {++seen[$6]} END {for (h in seen) print h, seen[h]}' auth.log
9.0.0.0 3
1.2.3.4 2
$ awk '/Failed password/ {++seen[$6]} END {for (h in seen) {++c; print h, seen[h];} print "uniqe hosts: " c }' auth.log
9.0.0.0 3
1.2.3.4 2
uniqe hosts: 2

awk's associative arrays are so cool!
 
That number (59) is likely not what you think it is. It's neither the total number of Failed password lines with IP addresses, nor the number of unique host IP addresses causing Failed password (since the sort is missing).

Note that grep | grep is a coding anti-pattern, something that's commonly seen, but that's substellar, and can easily be replaced with a better alternative. Why not use a single grep and save a process or three today? They are expensive beasts. If you show me two lines of your auth.log I'll come up with an awk(1) one-liner replacing also uniq and wc -l. In fact, I already started: :)

Bash:
$ cat auth.log
11:00 Failed password blah blah 1.2.3.4
12:00 Failed password blah blah 1.2.3.4 again!
13:00 Failed password blah blah 9.0.0.0
14:00 Good password, yay
15:00 Failed password blah blah 9.0.0.0 again!
16:00 Failed password blah blah 9.0.0.0 again!
17:00 Tired of logging
$ awk '/Failed password/ {print $6}' auth.log
1.2.3.4
1.2.3.4
9.0.0.0
9.0.0.0
9.0.0.0
$ awk '/Failed password/ {++seen[$6]} END {for (h in seen) print h, seen[h]}' auth.log
9.0.0.0 3
1.2.3.4 2
$ awk '/Failed password/ {++seen[$6]} END {for (h in seen) {++c; print h, seen[h];} print "uniqe hosts: " c }' auth.log
9.0.0.0 3
1.2.3.4 2
uniqe hosts: 2

awk's associative arrays are so cool!
The thing is that ip not always the sixth word in line, so can't be selected by $6.
 
Back
Top