- Shell script to delete directories older than n days
- 5 Answers 5
- Removing files older than 7 days
- Explanation:
- Alternatively, use:
- Delete files older than X days +
- 4 Answers 4
- Delete files older than 10 days using shell script in Unix [duplicate]
- Удаление файлов старше n дней в Linux
- Удаление файлов старше n дней в Linux
- Выводы
Shell script to delete directories older than n days
To they bare any relation on their actual creation/modification time? Because find could do it without looking at the name then.
What do you mean by «older than»? Are you referring to the time the directory was created, the time its contents were last changed, or something else? Be careful with some of the answers below; ctime is the inode change time. For a directory, it changes when files are added or removed from the directory.
5 Answers 5
This will do it recursively for you:
find /path/to/base/dir/* -type d -ctime +10 -exec rm -rf <> \;
Explanation:
- find : the unix command for finding files / directories / links etc.
- /path/to/base/dir : the directory to start your search in.
- -type d : only find directories
- -ctime +10 : only consider the ones with modification time older than 10 days
- -exec . \; : for each such result found, do the following command in .
- rm -rf <> : recursively force remove the directory; the <> part is where the find result gets substituted into from the previous part.
Alternatively, use:
find /path/to/base/dir/* -type d -ctime +10 | xargs rm -rf
Which is a bit more efficient, because it amounts to:
rm -rf dir1; rm -rf dir2; rm -rf dir3; .
With modern versions of find , you can replace the ; with + and it will do the equivalent of the xargs call for you, passing as many files as will fit on each exec system call:
find . -type d -ctime +10 -exec rm -rf <> +
-mtime was better for me as it checks content changes rather than permission changes, otherwise this was perfect.
The more efficient approach can backfire if you have too many folders to delete: stackoverflow.com/questions/11289551/…. For the same reason, in order to avoid deletion of the base folder it’s better to use -mindepth 1 (rather than /path/to/folder/* ).
If you want to delete all subdirectories under /path/to/base , for example
/path/to/base/dir1 /path/to/base/dir2 /path/to/base/dir3
but you don’t want to delete the root /path/to/base , you have to add -mindepth 1 and -maxdepth 1 options, which will access only the subdirectories under /path/to/base
-mindepth 1 excludes the root /path/to/base from the matches.
-maxdepth 1 will ONLY match subdirectories immediately under /path/to/base such as /path/to/base/dir1 , /path/to/base/dir2 and /path/to/base/dir3 but it will not list subdirectories of these in a recursive manner. So these example subdirectories will not be listed:
/path/to/base/dir1/dir1 /path/to/base/dir2/dir1 /path/to/base/dir3/dir1
So , to delete all the sub-directories under /path/to/base which are older than 10 days;
find /path/to/base -mindepth 1 -maxdepth 1 -type d -ctime +10 | xargs rm -rf
Removing files older than 7 days
As @Jos pointed out you missed a space between name and ‘*.gz’ ; also for speeding up the command use -type f option to running the command on files only.
So the fixed command would be:
find /path/to/ -type f -mtime +7 -name '*.gz' -execdir rm -- '<>' \;
Explanation:
- find : the unix command for finding files/directories/links and etc.
- /path/to/ : the directory to start your search in.
- -type f : only find files.
- -name ‘*.gz’ : list files that ends with .gz .
- -mtime +7 : only consider the ones with modification time older than 7 days.
- -execdir . \; : for each such result found, do the following command in . .
- rm — ‘<>‘ : remove the file; the <> part is where the find result gets substituted into from the previous part. — means end of command parameters avoid prompting error for those files starting with hyphen.
Alternatively, use:
find /path/to/ -type f -mtime +7 -name '*.gz' -print0 | xargs -r0 rm --
-print0 True; print the full file name on the standard output, followed by a null character (instead of the newline character that -print uses). This allows file names that contain newlines or other types of white space to be correctly interpreted by programs that process the find output. This option corresponds to the -0 option of xargs.
Which is a bit more efficient, because it amounts to:
rm file1; rm file2; rm file3; .
An alternative and also faster command is using exec’s + terminator instead of \; :
find /path/to/ -type f -mtime +7 -name '*.gz' -execdir rm -- '<>' +
This command will run rm only once at the end instead of each time a file is found and this command is almost as fast as using -delete option as following in modern find :
find /path/to/ -type f -mtime +7 -name '*.gz' -delete
I think when using find to do a batch deletion like all *.gz files, it would be important to make use of -maxdepth . The Find command seems to be recursive by default, and it will search all child directories for a matching pattern. This may be unwanted behavior, so it would be a good idea to use -maxdepth 1
for the completeness: you may also use -delete
find /some/where/ -name '*.log' -type f -mtime +7 -delete
this way you don’t run a command per file.
This is the best answer. Well done for placing the «-delete» portion at the end of the line. I strongly suggest anyone considering this method reads the man page prior to implementation.
Be careful removing files with find. Run the command with -ls to check what you are removing
find /media/bkfolder/ -mtime +7 -name ‘*.gz’ -ls . Then pull up the command from history and append -exec rm <> \;
Limit the damage a find command can do. If you want to remove files from just one directory, -maxdepth 1 prevents find from walking through subdirectories or from searching the full system if you typo /media/bkfolder / .
Other limits I add are more specific name arguments like -name ‘wncw*.gz’ , adding a newer-than time -mtime -31 , and quoting the directories searched. These are particularly important if you are automating cleanups.
find «/media/bkfolder/» -maxdepth 1 -type f -mtime +7 -mtime -31 -name ‘wncw*.gz’ -ls -exec rm <> \;
Delete files older than X days +
Possibly fun when I have files with spaces. E.g a file called «test one» and rm gets fed rm test one . (Which will delete a file called «test» and a file called «one», but not a file called «test one»). Hint: -delete or -print0
As a side note, always quote the argument provided by find to avoid issues with special characters, as mentioned in the answer’s first line. E.g.: find /path/to/files/ -exec somecommand ‘<>‘ \;
4 Answers 4
Be careful with special file names (spaces, quotes) when piping to rm.
There is a safe alternative — the -delete option:
find /path/to/directory/ -mindepth 1 -mtime +5 -delete
That’s it, no separate rm call and you don’t need to worry about file names.
Replace -delete with -depth -print to test this command before you run it ( -delete implies -depth ).
- -mindepth 1 : without this, . (the directory itself) might also match and therefore get deleted.
- -mtime +5 : process files whose data was last modified 5*24 hours ago.
Alternatively, if you want to do the same for all files NEWER than five days: find /path/to/directory/ -mindepth 1 -mtime -5 -delete
Note that every find argument is a filter that uses the result of the previous filter as input. So make sure you add the -delete as the last argument. IE: find . -delete -mtime +5 will delete EVERYTHING in the current path.
Note that this command will not work when it finds too many files. It will yield an error like:
bash: /usr/bin/find: Argument list too long
Meaning the exec system call’s limit on the length of a command line was exceeded. Instead of executing rm that way it’s a lot more efficient to use xargs. Here’s an example that works:
find /root/Maildir/ -mindepth 1 -type f -mtime +14 | xargs rm
This will remove all files (type f) modified longer than 14 days ago under /root/Maildir/ recursively from there and deeper (mindepth 1). See the find manual for more options.
Delete files older than 10 days using shell script in Unix [duplicate]
And take care that ./my_dir exists to avoid bad surprises !
find /home/scripts/*.script -mtime +10 type f -delete will be ok for delete these? 2012.11.21.09_33_52.script 2012.11.21.09_33_56.script 2012.11.21.09_33_59.script
It depends of the date of the modification, like what ls -l displays. Are the date the same as ls -l ? But a simple test will tell you =)
Be VERY careful to supply an absolute path on commands like these! Once, using a command very much like this in a cron job, I accidentally deleted every file on my production mail server older than 10 days, which I can tell you was no fun to recover from.
@DSimon Thanks for sharing your horror story to help us avoid our own! I had a few directories to do this to, so inspired by your comment, inside my for a in . loop, I added a if [ -d $a ]; then. to my script!
Just spicing up the shell script above to delete older files but with logging and calculation of elapsed time
#!/bin/bash path="/data/backuplog/" timestamp=$(date +%Y%m%d_%H%M%S) filename=log_$timestamp.txt log=$path$filename days=7 START_TIME=$(date +%s) find $path -maxdepth 1 -name "*.txt" -type f -mtime +$days -print -delete >> $log echo "Backup:: Script Start -- $(date +%Y%m%d_%H%M)" >> $log . code for backup . or any other operation . >> $log END_TIME=$(date +%s) ELAPSED_TIME=$(( $END_TIME - $START_TIME )) echo "Backup :: Script End -- $(date +%Y%m%d_%H%M)" >> $log echo "Elapsed Time :: $(date -d 00:00:$ELAPSED_TIME +%Hh:%Mm:%Ss) " >> $log
The code adds a few things.
- log files named with a timestamp
- log folder specified
- find looks for *.txt files only in the log folder
- type f ensures you only deletes files
- maxdepth 1 ensures you dont enter subfolders
- log files older than 7 days are deleted ( assuming this is for a backup log)
- notes the start / end time
- calculates the elapsed time for the backup operation.
Note: to test the code, just use -print instead of -print -delete. But do check your path carefully though.
Note: Do ensure your server time is set correctly via date — setup timezone/ntp correctly . Additionally check file times with ‘stat filename’
Note: mtime can be replaced with mmin for better control as mtime discards all fractions (older than 2 days (+2 days) actually means 3 days ) when it deals with getting the timestamps of files in the context of days
-mtime +$days ---> -mmin +$((60*24*$days))
Удаление файлов старше n дней в Linux
Пользователи Linux иногда сталкиваются с ситуацией, когда нужно почистить определенный каталог, удалив из него старые, неиспользуемые файлы. Через стандартный проводник это делать далеко не всегда удобно. Но данную процедуру очень просто выполнять через терминал.
По ходу данной статьи мы разберемся с удалением файлов старше определенного количества дней в Ubuntu. Заодно объясним некоторые нюансы этой процедуры.
Удаление файлов старше n дней в Linux
Для терминала Ubuntu существует специальная команда find, которая отвечает за поиск файлов на компьютере. А с помощью опции -mtime получится найти только те файлы, дата изменения которых старше заданного временного промежутка. В качестве примера возьмем каталог Downloads и срок в 35 дней.
Откройте терминал и запустите следующую команду:
find ~/Downloads -type f -mtime +35
Вам необязательно действовать напрямую и стирать сразу же все файлы. Их можно отсортировать дополнительно по еще одному признаку, например, по названию или расширению. Для этого есть опция -name, которая прописывается сразу же после директории. Если нужно избавиться только от zip-архивов, то подойдет такая команда:
find ~/Downloads -name «*.zip» -type f -mtime +35 -delete
Ну и напоследок хотелось бы упомянуть, что при запуске терминала Ubuntu из конкретной папки вручную директорию прописывать не придется. Это можно сделать через стандартное приложение Файлы, если перейти к нужному каталогу, кликнуть правой клавишей мыши по пустому месту и в контекстном меню выбрать пункт Открыть в терминале.
Тогда команда для поиска, если она еще нужна, сократится до следующего варианта:
А для удаления не забудьте в конце дописать опцию -delete:
Выводы
По ходу данной статьи мы вкратце объяснили, как можно в конкретном каталоге отыскать файлы старше определенного возраста через терминал Ubuntu, а также как удалить файлы старше n дней linux. Сама по себе процедура довольно простая, но может сэкономить много времени при чистке уже ненужных данных с компьютера.
Обнаружили ошибку в тексте? Сообщите мне об этом. Выделите текст с ошибкой и нажмите Ctrl+Enter.