3

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 ??

5
  • 4
    What version of find do you have? GNU and BSD finds at least supports regex matching with -regex Dec 7, 2016 at 14:19
  • test this find -type f -mtime +5 -regextype "egrep" -regex '.*[[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}.*
    – Baba
    Dec 7, 2016 at 14:26
  • 1
    @Babyy you should write that up as an answer with some exposition Dec 7, 2016 at 16:02
  • @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
    – Baba
    Dec 7, 2016 at 19:38
  • Has the literal date representation found to be 5 or more days old, or does the mtime of the file matter? Mar 17, 2018 at 18:06

2 Answers 2

4

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.

1

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!

You must log in to answer this question.

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