Bash Oneliners - Count, Sort, and Print Objects

There are several Bash one-liners that I’ve been shown by the talented Linux admins I’ve had the pleasure of working with over the years.

This one will take something you’re interested in, say IPs from a log file, and print them in a sorted list.

For example, say I wanted to see the bots trying to access SSH. The /var/log/auth.log (Debian) prints lines like the following:

2023-09-04T06:58:01.540076+00:00 HOST sshd[249345]: Invalid user blank from 1.1.1.1 port 20082

First, we need to get the IP addresses:

# grep "Invalid user" /var/log/auth.log | awk '{print $8}'

The awk '{print $8}' command will print the eighth space-separated column. This is more reliable than cut as the awk command will give you the right value regardless of the number of spaces, if the space happens to be a tab etc.

This command gives a list of IP addresses as they appeared in the file, e.g.:

1.1.1.1
3.3.3.3
1.1.1.1
5.5.5.5
1.1.1.1
2.2.2.2
6.6.6.6
1.1.1.1
4.4.4.4
2.2.2.2
3.3.3.3
1.1.1.1
1.1.1.1

The one-liner will take that list and print the number of times the IP appears in the list and sort them. The commands to append to the grep output are the following:

sort | uniq -c | sort -n

The commands work as follows:

1.1.1.1
1.1.1.1
1.1.1.1
1.1.1.1
1.1.1.1
1.1.1.1
2.2.2.2
2.2.2.2
3.3.3.3
3.3.3.3
4.4.4.4
5.5.5.5
6.6.6.6
      6 1.1.1.1
      2 2.2.2.2
      2 3.3.3.3
      1 4.4.4.4
      1 5.5.5.5
      1 6.6.6.6
      1 4.4.4.4
      1 5.5.5.5
      1 6.6.6.6
      2 2.2.2.2
      2 3.3.3.3
      6 1.1.1.1

The default is to order from least to most. You can reverse this with -r.

The entire command looks like this:

# grep "Invalid user" /var/log/auth.log | awk '{print $8}' | sort | uniq -c | sort -n