1

Within a given directory in linux environment, I need to pick all files modified after a certain date (let's say 7 days) as well as all directories (only in root directory, hence non recursively) created after the same date.

After that, I have to take care of 3 directories which except the last given rule. For these, the process has to be recursive within each of them. In one of these directories, there's a file to be excluded no matter what.

Finally, I have to add all the objects matching these patterns to a single .tar archive. Every file/directory must of course keep full relative path within the .tar file (starting from base directory).

So let's assume we have:

myHome
|-- normalDir1                  //  older than 7 days
|   |-- blah.txt
|   |-- to_be_excluded_nmw.txt  //  should never be included anyways
|   `-- poems.txt
|-- normalDir2                  //  created yesterday
|   |-- blah2.txt               /*
|   |-- whatever2.txt            *  Since it's a normal directory,
|   |-- whatever3.txt            *  I want to exclude these files from .tar
|   `-- poems2.txt               */  
|-- exceptionDirectory1         //  older than 7 days
|   |-- actions                 //  older than 7 days
|   |   `-- power.sh            //  older than 7 days
|   `-- events                  //  older than 7 days
|       |-- deploy.php          //  older than 7 days
|       `-- set.php             //  older than 7 days
|-- exceptionDirectory2         //  older than 7 days
|   |-- actions2
|   |   `-- power2.sh           //  created yesterday
|   `-- events2                 //  older than 7 days
|       |-- deploy2.php         //  created yesterday
|       `-- set2.php            //  older than 7 days
|-- file_to_be_updated.php      //  created yesterday
`-- file_NOT_to_be_updated.php  //  older than 7 days

the resulting .tar should contain:

./normalDir2/
./exceptionDirectory2/actions2/power2.sh
./exceptionDirectory2/events2/deploy2.php
./file_to_be_updated.php

I've created this script:

#!/bin/bash
TODAY=`date --rfc-3339=date`
FILENAME=$TODAY-package.tar
find ./require ! -name db_connection.php         ! -path ./require -mtime -7 -print | xargs tar cvf `date --rfc-3339=date`-package.tar
find ./img                                       ! -path ./img     -mtime -7 -print | xargs tar uvf `date --rfc-3339=date`-package.tar
find ./plugin                                    ! -path ./plugin  -mtime -7 -print | xargs tar uvf `date --rfc-3339=date`-package.tar
find . -maxdepth 1 ! -name $TODAY-package.tar.gz ! -path .         -mtime -7 -print | xargs tar uvf `date --rfc-3339=date`-package.tar

but it doesn't seem to work properly as it quits almost immediately with this error:

tar: ./img: Impossibile open: Is a directory

Notice "require", "img" and "plugin" being the three special directories to be treated recursively. What's wrong with the script? Thank you for your assistance.

2
  • 1
    Did you try to use directly tar --after-date ?
    – Hastur
    May 14, 2014 at 11:45
  • Actually I didn't, maybe my approach is a little winding. But I'd still have to take care about the exceptions as stated above, and I fear simply following your tip wouldn't solve the whole thing.
    – Seether
    May 14, 2014 at 11:59

3 Answers 3

1

What is causing the error is that you have spaces or other special characters in the filenames under ./img.

Instead of using the -print option to find, use -print0 and the corresponding -0 option to `xargs':

 find ./img ! -path ./img -mtime -7 -print0 | xargs -0 tar uvf `date --rfc-3339=date`-package.tar
1
  • I've tried this solution first as it was the most similiar to mine, but doesn't seem to fix the issue.
    – Seether
    May 14, 2014 at 13:25
0
  • Rather than find ./foo ! -path ./foo you can use find -mindepth 1 ./foo. This ensures that only files inside the specified paths are printed.
  • If you have GNU tar you can use --exclude=PATTERN. That way you should be able to write something like this:

    today="$(date --rfc-3339="date")"
    last_week="$(date --rfc-3339="date" --date="-7 days")"
    tar --no-recursion --exclude=db_connection.php --after-date="$last_week" cvf "${today}-package.tar" .
    tar --after-date="$last_week" uvf "${today}-package.tar" ./require ./img ./plugin
    
2
  • That's nice and I've modified my script already, but the error remains. (EDIT: was referring only to first point when writing)
    – Seether
    May 14, 2014 at 12:04
  • Running the copy-pasted version of this script results in a error, perhaps the "cvf" and "uvf" params are misplaced. I tried moving them on first position without much success, the best I managed to achieve is obtaining a couple of tars named "--no-recursion" and "--after-date", obviously with no files/directories exclusion rules applied.
    – Seether
    May 14, 2014 at 13:35
0

I write it on the fly, try if it functions something around

tar cvf   --no-recursion --after-date $yourdate $TarFile * */* 
tar uvrf  --after-date $yourdate $TarFile ./require ./plugin ./img

You must log in to answer this question.

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