0

I'm working on a complicated grep, something like grep -E -i "first|next" *.txt, and I get results like:

logs.10.txt:2022-10-07 10:33:05.6673 | ClassName | [Info] | Inside function first(), before Unsubscribe() |
logs.10.txt:2022-10-07 10:33:05.6673 | ClassName | [Info] | Inside function first(), after Unsubscribe() |

Now, I would like to order the results, based on timestamp, which looks quite easy:

Prompt> grep ... | sort -t: -k2

... but there's a catch: as you see the "before" and "after" regularly happen within the same tenth of millisecond, and the sort command switches them:

logs.10.txt:2022-10-07 10:33:05.6673 | ClassName | [Info] | Inside function first(), after Unsubscribe() |
logs.10.txt:2022-10-07 10:33:05.6673 | ClassName | [Info] | Inside function first(), before Unsubscribe() |

I have already tried adding an extra field delimiter to the sort command, but this does not work:

Prompt> grep ... | sort -t:| -k2

Is it possible to:

  • add a length parameter to the sort command? (Only sort on the first 24 characters) Or:
  • add a second field delimiter? (Like the pipe character)

1 Answer 1

1

In -k2 there is no stop position. The stop position defaults to the line's end. after sorts before before, hence the problem.

If you want to sort by timestamp only then one of possible solutions for your particular case is -t: -k2,4.7. This is why:

logs.10.txt:2022-10-07 10:33:05.6673 | whatever
start=2     ^                        2nd field begins here
                          ^          3rd field begins here
                             ^       4th field begins here
stop=4.7                           ^ 7th character of the 4th field
whole key   ^^^^^^^^^^^^^^^^^^^^^^^^

logs.10.txt looks like an arbitrary name. Keep in mind some names can break our logic. E.g. if log:foo.txt appeared where you expect logs.10.txt then the colon in it would be an instance of separator we didn't anticipate.

Additionally you want -s, stable sort.

A sorting algorithm is said to be stable if two objects with equal keys appear in the same order in sorted output as they appear in the input array to be sorted.

sort -s -t: -k2,4.7

My tests with GNU sort 8.30 suggest that -t: -k2,2.24 works, despite the fact the 2nd field is shorter than 24 characters. This would be "only sort on the first 24 characters" you requested. I haven't found (yet) any clear documentation of this behavior. If I were you, I wouldn't use -k2,2.24, just in case. -k2,4.7 is valid for sure.

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.