1
Feb  7  domainserver dovecot[37495]: auth(default): od(tjones): lookup failed for user: tjones

Above is a sample output of what I'd like to sort. I'd like to sort by date on the first column, but also by tjones on the right, which would be the user.

Basically, I want all instances of tjones grouped together, but sorted by date. I really have no idea what command to use in order to do this, or if I need to use the awk command to rearrange columns.

There are obviously more users than tjones, so I'd just like to sort by those two columns

I tried the following, but it brought up an error "sort: multi-character tab `\t'"

sort -t '\t' -k1,1 -k5,5n auth_2014uniq.txt > auth_2014uniqtest
2

sort allows sorting by particular fields with the -k option:

sort -k11 -k1,2 data

will sort first by field 11 (username) and then by fields 1 and 2 together (date). Note that order is important here: it sorts by the first -k option first, and uses the next to break ties (and so on).

This is very dependent on the exact output you have there - each sequence of spaces is a field separator, so "lookup failed for" is three different fields.

The edit makes it look like your real data has fields that are tab-separated, although I can't figure out where the tabs are in that case. If so, you need to provide a literal tab as the argument to -t - sort doesn't understand escapes, and your shell likely doesn't expand \t either. Either press Ctrl-VTab to write a literal tab character in there, or make one to substitute in: something like "$(echo -ne '\t')" is one option. If this is the case, substitute the appropriate field numbers in.

-k5,5n is a numeric sort on field 5 only - since none of your data is numeric that looks like a mistake.


GNU sort and some others include a -M month sort extension which you can use to put months in order. This may or may not be available to you; it is also in FreeBSD and OS X, but not the other BSDs and not commercial Unices. If it is available, -k1,1M -k2,2n will sort dates by correct month/day order. Note that it is also dependent on your locale: if your log file and your environment use a different localisation, this won't work. Without this, they will be grouped by month and sorted by date within each month correctly.

  • -k1,2M does the month sort properly - if -t is correctly set. – mikeserv Jul 31 '14 at 2:05
0
sed -n 's/\(.*user: \)\([^ ]*\)$/\2 \1\2/p' <<\DATA |\
sort -t' ' -k1,1 -k2,3M |\
sed 's/[^ ]* //'
Feb  7  domainserver dovecot[37495]: auth(default): od(tjones): lookup failed for user: tjones
Feb  8  domainserver dovecot[37495]: auth(default): od(tjones): lookup failed for user: tjones
Feb  5  domainserver dovecot[37495]: auth(default): od(lbones): lookup failed for user: lbones                                                        
Jan  7  domainserver dovecot[37495]: auth(default): od(chaz): lookup failed for user: chaz                                                            
Mar  7  domainserver dovecot[37495]: auth(default): od(lbones): lookup failed for user: lbones                                                        
DATA

OUTPUT

Jan  7  domainserver dovecot[37495]: auth(default): od(chaz): lookup failed for user: chaz
Feb  5  domainserver dovecot[37495]: auth(default): od(lbones): lookup failed for user: lbones
Mar  7  domainserver dovecot[37495]: auth(default): od(lbones): lookup failed for user: lbones
Feb  7  domainserver dovecot[37495]: auth(default): od(tjones): lookup failed for user: tjones
Feb  8  domainserver dovecot[37495]: auth(default): od(tjones): lookup failed for user: tjones

This prunes the data first, by only selecting lines that contain the string user: and copying the following field to the head of the line. So, given the following data:

*CRUFT*user: nospaces$

Where $ represents the end of the line, the first thing sed does is:

nospaces *CRUFT*user: nospaces$

...copy nospaces to the head of the line. This is a common practice in these sorts of operations, because often even a variation of 1 or 2 in the number of fields in any of the lines can drastically affect the sort. It is far better to copy the important fields to the start of the line in order to sort only on those. In any case, that is what occurs here.

So sed passes its edited data over the |pipe to sort, which sorts first on the first field - the username - and next by MONTH on a -key combining both the second and third fields. The result is all lines are grouped by username and each grouping is sorted by date.

Last sort hands its data back to sed over another |pipe and sed strips the first field of the line - which is only there because it copied it there in the first place.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.