Question

I'm not sure if I'm using regular expressions in bash correctly. I'm on a Centos system using bash shell. In our log directory, there are log files with digits appended to them, i.e.

stream.log
stream.log.1
stream.log.2 
...
stream.log.nnn  

Unfortunately there are also log files with the new naming convention,

stream.log.2014-02-14 
stream.log.2014-02-13

I need to get files with the old log file naming format. I found something that works but I'm wondering if there's another more elegant way to do this.

ls -v stream.log* | grep -v 2014

I don't know how regular expressions work in bash and/or what command (other than possibly grep) to pipe output to. The cmd/regex I was thinking of is something like this:

ls -v stream.log(\.\d{0,2})+

Not surprisingly, this didn't work. Maybe my logic is incorrect but I wanted to say from the cmdline list files with the name stream.log with an optional .xyz at the end where xyz={1..999} is appended at the end. Please let me know if this is doable or if the solution I came up with is the only way to do something like this. Thanks in advance for your help.

EDIT: Thanks for everyone's prompt comments and reply. I just wanted to bring up that there's also a file called stream.log that doesn't any digits appended to it that also needs to make it into my ls listing. I tried the tips in the comment and answer and they work but it leaves out that file.

Was it helpful?

Solution

You can do this with extended pattern matching in , e.g.

> shopt -s extglob
> ls *'.'+([0-9])

Where

+(pattern-list)
     Matches one or more occurrences of the given patterns

And other useful syntaxes.

?(pattern-list)
     Matches zero or one occurrence of the given patterns
*(pattern-list)
     Matches zero or more occurrences of the given patterns
@(pattern-list)
     Matches one of the given patterns
!(pattern-list)
     Matches anything except one of the given patterns

Alternatively without extended pattern matching could use a less neat solution

ls *'.'{1..1000} 2>dev/null

And replace 1000 with some larger number if you have a lot of log files. Though I would prefer the option to this one.

OTHER TIPS

An approach using sed:

ls -v stream.log* | sed -nE '/log(\.[0-9]+)?$/p'

and one using egrep:

ls -v stream.log* | egrep 'log(\.[0-9]+)?$'

These print out lines that end in "log" and optionally a period and any positive number of digits, followed by the end of the line.

You can this much more simply by just focusing on the dash '-' in the old logfile format. Here is the minimal version:

ls *-*

This may be a little safer if there are different types of logfiles in the same directory:

ls stream.log.*-*

To ensure that you get the one extra file, it does not make sense to generate a confusing regex that will fit it - just include it on the ls line:

ls stream.log stream.log.*-*

refer @BroSlow's answer, here is the fix which will include stream.log as well.

shopt -s extglob
ls stream.log*(.)*([0-9])

stream.log  stream.log.1  stream.log.2
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top