find and delete files older than specific days and have specific string in filenames

6,480

Solution 1

Using GNU find:

find . -type f -mtime +5 \
    -regextype egrep -regex '.*[0-9]{4}-[0-9]{2}-[0-9]{2}[^/]*$' \
    -delete

The regular expression will match any string in the basename of a pathname that contains a date on the form YYYY-MM-DD. Note that we may also match XXYYYY-MM-DDZZ where XX and ZZ are some other characters.

The [^/]*$ at the end makes sure that we're actually matching the expression against the basename of the current pathname, and means "no / for the rest of the string, please".

Using a shell wildcard pattern instead (easier to maintain):

find . -type f -mtime +5 \
    -name '*[0-9][0-9][0-9][0-9]-[01][0-9]-[0-3][0-9]*' \
    -delete

Note that -mtime +5 is for files whose age as an integer number of days is strictly greater than 5, so 6 days and over. For files 5 days old or over, you'd need -mtime +4.

Solution 2

Assuming you are working with GNU tools, this should prevent the false-positives spoken of by Babyy:

find /directory -type f -mtime +5 -print | while read f; do
    n=`basename "$f"`
    d=`expr "X$n" : 'X.*\([0-9]\{4,\}-[0-9]\{2\}-[0-9]\{2,\}\)'` # (1)
    test -n "$d" || continue                                     # (2)
    date -d "$d" >/dev/null 2>&1 && rm "$f"                      # (3)
done

Remarks:

  • (1) assigns the date part of the file name to d. It includes leading and trailing digits. If there is no date part, then the empty string is assigned to d.
  • (2) will skip to the next iteration if "$d" is the empty string. This is needed to prevent (3) from removing the file, since date -d will succeed if given the empty string as its argument. (This seems like a bug in GNU date, but maybe that behavior was intended.)
  • (3) will remove the file if "$d" contains a valid date. Note that date -d will succeed if the year part of the date contains more than 4 digits, as long as the month and day parts are valid. Now that's really future-proofing your code!
Share:
6,480

Related videos on Youtube

AVJ
Author by

AVJ

Updated on September 18, 2022

Comments

  • AVJ
    AVJ almost 2 years

    To delete files older than 5 days from a directory, we can use command.

    find /directory -type f -mtime +5 -delete
    

    But, in my case, I want to delete only those files having 'YYYY-MM-DD' in their names and which are older than 5 days.

    Below are some example of filenames:

    TEST_2016-11-20_14_02_52.log
    server.log.2016-11-13
    locsub.log.2016-12-04
    wsgi.txt.2016-12-01
    

    Only files having name in format 'YYYY-MM-DD' and older than 5 days should get deleted.

    How to match filenames in find command using regex ??

    • Baba
      Baba over 7 years
      test this find -type f -mtime +5 -regextype "egrep" -regex '.*[[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}.*
    • Eric Renouf
      Eric Renouf over 7 years
      @Babyy you should write that up as an answer with some exposition
    • Baba
      Baba over 7 years
      @EricRenouf my answer is not e prefect! because my regex match with dddd-dd-dddddd* or 2016-99-44 or ... ; if you can edit and resolve this problem post it for answer
    • user unknown
      user unknown over 6 years
      Has the literal date representation found to be 5 or more days old, or does the mtime of the file matter?