2

I have a folder containing daily logs, named as :

system-2013-01-01.log
system-2013-01-02.log
system-2013-01-03.log
system-2013-01-04.log
system-2013-01-05.log
system-2013-01-06.log
system-2013-01-07.log
system-2013-01-08.log
...
system-2013-01-31.log

How can I select ( and copy ) the logs from 2013-01-01 to 2013-01-15 ?

Raptor
  • 305

2 Answers2

2

bash supports brace expansion, which allows you to specify multiple values, or even ranges, to be expanded in a command. For example,

$ echo {1..5}
1 2 3 4 5
$ echo foo_{01..05}
foo_01 foo_02 foo_03 foo_04 foo_05

So you can easy specify the range of files to copy as

cp system-2013-01-{01..31}.log /some/destination/dir

which bash will expand to

cp system-2013-01-01.log system-2013-01-02.log system-2013-01-03.log ...
1

If you have a file for every day, you can use a sequence expression in braces:

cp -p system-2013-01-{01..15}.log /elsewhere

If you don't have a file for every day, you can use character patterns.

cp -p system-2013-01-0[1-9].log system-2013-01-1[0-5].log /elsewhere

If there is no matching file in one of the two ranges, the pattern will be left unexpanded. Set the nullglob option (bash-specific) to avoid this (shopt nullglob).

Zsh makes this easier thanks to its <start-stop> numeric range glob pattern.

cp -p system-2013-01-<1-15>.log /elsewhere

A different approach that doesn't require zsh and scales well to more complex cases is to use find to generate the list of files. You don't need to worry about non-matches: cp will be executed for each match.

find . \( -name 'system-2013-01-0[1-9].log' -o -name 'system-2013-01-1[0-5].log' \) -exec cp -p {} /elsewhere \;

Add -type d -prune -o after find . to avoid recursing into subdirectories.