15

I am trying to show all instances of a particular message from the syslog in chronological order by doing something like the following:

grep squiggle /var/log/messages*

Unfortunately the glob pattern matches the currently active file first. eg.

/var/log/messages
/var/log/messages-20120220
/var/log/messages-20120227
/var/log/messages-20120305
/var/log/messages-20120312

This means that recent messages show up first followed by the historical messages in chronological order.

Is it possible to adjust the glob pattern behaviour somehow to make the empty match (ie. just messages) show up at the end of the list?

If not, what would be a good way to address this problem?

1
  • 2
    You could reverse output using tac: grep squiggle /var/log/messages* | tac...
    – pbm
    Mar 13, 2012 at 10:17

3 Answers 3

17

In zsh, you can control the order of matches (among other things) with a glob qualifier.

echo /var/log/messages*        # usual lexicographic order
echo /var/log/messages*(On)    # reverse lexicographic order
echo /var/log/messages*(om)    # reverse chronological order (ascending mtime)
echo /var/log/messages*(Om)    # chronological order order (descending mtime)

(See the manual for more possibilities.) You can even define your own sorting order by supplying a comparison function in recent versions, with oe or o+.

Here, the proper order of files is chronological order. You can emulate it easily based on the name, though, and that works even in bash:

grep squiggle /var/log/messages{-*,}
3
  • 1
    I'm increasingly impressed by zsh the more I read about it.
    – Burhan Ali
    Mar 14, 2012 at 10:20
  • Can I get files (in order) from zsh and pass them back to bash? Jan 20, 2019 at 20:26
  • @Wowfunhappy Yes but you need to be careful to treat special characters correctly. Ask a new question. Jan 21, 2019 at 8:24
8

I don't know of a way to change the globbing order, but there's an easy workaround for your case:

grep squiggle /var/log/messages-* /var/log/messages

i.e. don't match the messages files in your glob pattern, and add it to the end of grep's argument list.

2
  • Thanks for that. Been making the problem more complex than it needed to be!
    – Burhan Ali
    Mar 13, 2012 at 12:28
  • 1
    Or for extra fanciness and less redundancy, use grep squiggle /var/log/messages{-*,}. (Called "bash brace expansion" if you want to google it.)
    – Wildcard
    Sep 23, 2016 at 0:32
4

You can use backticks combined with ls -tr (sort by mod time and in reverse) like this:

grep squiggle `ls -tr /var/log/messages*`

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .