I need to to delete all files from a folder with below mentioned condition.

File Name pattern: fileNameBeginDateEndDate.txt (begin and end date in YYYYMMDD format)

All files in which current date is not in between the begin date and end date need to be deleted.

Example, if today's date is 2018-01-16,

  • File that need to be deleted: File2016010120170101.txt
  • File that should not be deleted: File2016010120190101.txt

Thanks in Advance!


This filter will only output filenames matching your criteria, that is those that needs to be deleted:

perl -MTime::Piece -ne 'BEGIN { $now=localtime->ymd("")} ($s,$e)=($_=~m/(\d{8})(\d{8})\./); print $_ if $e lt $now || $s gt $now'


 echo "File2016010120170101.txt" | perl -MTime::Piece -ne 'BEGIN { $now=localtime->ymd("")} ($s,$e)=($_=~m/(\d{8})(\d{8})\./); print $_ if $e lt $now || $s gt $now'
 echo "File2016010120190101.txt" | perl -MTime::Piece -ne 'BEGIN { $now=localtime->ymd("")} ($s,$e)=($_=~m/(\d{8})(\d{8})\./); print $_ if $e lt $now || $s gt $now'

Depending on how you have your initial list of filenames, you can preprocess the list and then just run xargs rm on the result.

I would advise on adapting the regex to be as strict as possible depending on your files. And/Or to review the files about to be deleted before really deleting them.


find + bash solution:

find -type f -regextype posix-egrep -regex ".*/File[0-9]{16}\.txt" -exec \
bash -c 'd=$0; f="$1"; [[ $f =~ File([0-9]{8})([0-9]{8})\.txt ]]; 
         [[ "$d" -lt "${BASH_REMATCH[1]}" || "$d" -gt "${BASH_REMATCH[2]}" ]] && rm "$f"' \
         $(date +"%Y%m%d") {} \;

With zsh:

set -o  extendedglob # best in ~/.zshrc
rm ./*[0-9](#c16).txt(e'{! ((now >= REPLY[-20,-13] && now <= REPLY[-12,-5] ))}'))
  • (%) parameter expansion flag that turns on prompt expansion for the expansion of the parameter.
  • ${:-value}: form of Bourne-like ${var:-value} expansion without var, so it expands to the given value.
  • %D{%Y%m%d}: prompt expansion to expand to today's date in that format. Another approach would have been to use zmodload zsh/datetime; strftime -s now %Y%m%d $EPOCHSECONDS or use the system's date command: now=$(date +%Y%m%d).
  • (#c16) extendedglob operator to match 16 of the previous atom (similar to ksh93's {16}([0-9])).
  • (e:code:): glob qualifier to select files based on the evaluation of the code.
  • REPLY[-20,-13]: 20th last to 13th last characters of $REPLY (that holds the path of the file being examined).

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.