I have a large number of files in a folder each with the date as the filename.
For example


similarly for other months 20130201 to 20130230, the pattern is [Year][Month][Day]. I need to make a tar file of the first fifteen files from JAN to APRIL (i.e 2013[01-04][01-15]), since double digit number range is not allowed in grep. How should I search this pattern?


With zsh:

tar zcf ~/file.tar.gz 20130<1-4><1-15>

If you have to use bash:

shopt -s extglob
tar zcf ~/file.tar.gz 20130[1-4]@(0?|1[0-5])

Use find to find the filenames:

find . -maxdepth 1 -name "20130[1-4]0?" -o -name "20130[1-4]1[0-5]" 

check if that is the correct set, and use the output as input for cpio:

find . -maxdepth 1 -name "20130[1-4]0?" -o -name "20130[1-4]1[0-5]" | cpio --create --format=ustar -O file.tar

@richard pointed out this could traverse in sub-directories (if a sub-directory matches the pattern) (and that shell expanded the pattern, corrected).

Expanding on the commandline runs the risk of the commandline becoming too long, which might happen if you had a file every few seconds for every day (20130101-00005, 20130101-00007. Piping the filename into cpio does not have problem.

  • 1
    Note it is not find that is doing the work here, but the shell. Warning will recurse directories, use echo instead of find to not do this. Dec 13 '13 at 11:15
  • would'nt the space after question mark give an error? Dec 13 '13 at 11:16
  • @Aditya why? it needs the space. Dec 13 '13 at 11:19
  • @richard Sorry! my mistake just looked at an example of it Dec 13 '13 at 11:22
  • Maybe call these first in your script shopt -s nullglob; shopt -u failglob, to stop it failing when a file is not found. Dec 13 '13 at 11:28

The grep bit is.

grep -zE "^20130[1-4](0[1-9]|1[0-5])$"
  • std grep will work as well. Since this particular pattern happens to want months 01-04, the first 0 can be included with the year. So, grep '20130[1-4][01..15]' will match the specified range.
    – bsd
    Dec 13 '13 at 11:44
  • 2
    @bdowning, no, [01..15], same as [015.] matches any of those 4 characters 0, 1, ., or 5. Dec 13 '13 at 11:47

You can tar czvf file.tar.gz $(ls | grep "201301\|201302\|201303\|201304" | grep -v "16\|17\|18\|19\|20\|21\|22\|23\|24\|25\|26\|27\|28\|29\|30\|31") from the base directory.

  • 3
    Beware though this should work it is fragile: e.g. if the year was 2016 it would not work. Dec 13 '13 at 11:17

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.