I am writing zsh script in which I have to get the date of 90th previous day from current date i.e I have to subtract 90 days from current date. Then I have to check the folders which have different dates as their names. I have to compare the directory date with the subtracted date and if the result is greater than the subtracted date, I have to delete the directory.
For example:
Let us say the current_date = 20131130 (yyyymmdd)
subtracted_date=current_date - 90 days
lets say there is a folder 20130621
Now this folder name should be compare with the subtracted date. If greater than subtracted_date then i have to delete the directory.
find path -type d -ctime +90 -exec rm -rf {} \;
should find all directories older than 90 days and use rm -rf on them
Be careful with that command though you will probably want to test it first with this
find path -type d -ctime +90 -exec echo {} \;
in order to keep certain folders consider -mtime instead of -ctime and touch the folder every so often
replace path above with the actual path you want to scan and delete
explanation
find is the command
path is the root directory you want to scan
-type d means look for directories only
-ctime +90 means created time older than 90 days
-exec rm -rf {} \; means remove recursively and force delete of the items which were found
-mtime is modified time
The second command will list out all folder which will be deleted so is much safer to run while you are testing
List directories before delete
find . -type d -ctime +60 -ls
List files before delete
find . -type f -ctime +60 -ls
Delete directories in current directory
find . -type d -ctime +60 -exec rm -rf {} \;
Delete files in current directory
find . -type f -ctime +60 -exec rm -rf {} \;
You can use the date command to find the date 90 days earlier to the current one. The following script should give you a list of directories that need to be deleted:
del=$(date --date="90 days ago" +%Y%m%d)
for i in `find . -type d -name "2*"`; do
(($del > $(basename $i))) && echo "delete $i" || echo "dont delete $i"
done
To perform the actual deletion of directories, you can replace the third line with the following:
(($del > $(basename $i))) && rm -rf $i
For example, if your current directory contains the following folders:
$ ls -1F
20120102/
20130104/
20130302/
20130402/
20130502/
20130602/
20130702/
Executing the above script would tell:
$ bash cleanup
delete ./20130302
delete ./20130104
delete ./20120102
delete ./20130402
dont delete ./20130702
dont delete ./20130502
dont delete ./20130602
You can also use the following command to delete all files in the current directory by date .
[jamshi#cpanel ~]$ rm -rf ls -l | grep 'Jul 19 15:32' | tr -s ' ' | cut -d ' ' -f9
Related
I want to delete logs which was greater than 100 mb and it should not return or delete current >month logs
Using (GNU) find & date:
find /path -type f -size +100M -mtime +$(date --date=yesterday +%d) -delete
where /path is where your logs are located. -mtime $(date --date=yesterday %d) means any files last modified more than day of month as of yesterday.
Make sure you test this before you use it, say, by using -ls to print the files instead of deleting them, or prompt before deleting each file with -exec rm -i {} \;.
With find you can use age and size filters and then RM.
find /path/to/files -mtime +30 -size +100M -exec rm {}
I haven't tested it
I was trying to remove all git files from a repository with this:
find . -name ".git*" -exec rm -rf {} \;
However, rm warns that files could not be deleted (because their parent directory has already been deleted).
Is there a way to get find to stop recursing when it finds a matching directory?
E.g. find...
/.gitmodules
/.git/stuff
/.git/.gitfile
... produces
/.gitmodules
/.git
Use -depth:
find . -depth -name ".git*" -exec rm -rf {} \;
This would allow you to process the files or subdirectories first before their parent directories.
I'm currently running successful mysql backups, and, on some sites, I'm deleting files older that 7 days using this command
find /path/to/file -mtime +7 -exec rm -f {} \;
What I'd like to do, because I'm paranoid and would still like some archived information, is delete files older than 31 days, but maintain at least one file from each previous month, perhaps spare any file that was created on the 1st of the month.
Any ideas?
You can also write a script to contain something like this using xargs:
find /path/to/files -mtime +7| xargs -i rm {};
then add the script to your cron job
The grep is almost right, it only has one space too many. This works (at least for me, I use Debian):
rm `find /path/to/file -type f -mtime +7 -exec ls -l {} + | grep -v ' [A-S][a-z][a-z] 1 ' | sed -e 's:.* /path/to/file:/path/to/file:g'`
You can create a file with these commands:
SRC_DIR=/home/USB-Drive
DATE=$(/bin/date "+%4Y%2m%2d%2H%2M")
TIME_STAMP=$(/bin/date --date 'now' +%s)
TIME_CAL=$[$TIME_STAMP-2592000+25200] #last day, 25200 is my GMT+7hour
TIME_LAST=$(/bin/date --date "1970-01-01 $TIME_CAL sec" "+%4Y%2m%2d%2H%2M")
/bin/touch -t ${TIME_LAST} /tmp/lastmonth
/usr/bin/find -P -H ${SRC_DIR} ! -newer /tmp/lastmonth -type d -exec rm -r {} \;
You can modified last command based on what you want to delete, in this case I want to delete sub-folders in SRC_DIR. With the 'time attribute' more than 1 month ago.
Kind of ugly, but you can try parsing the output of ls -l
rm `find /path/to/file -type f -mtime +7 -exec ls -l {} + | grep -v ' [A-S][a-z][a-z] 1 ' | sed -e 's:.* /path/to/file:/path/to/file:g'`
Or write a script to get the list then run rm on them one at a time.
I have hundreds of directories and files in one directory.
What is the best way deleting only directories (no matter if the directories have anything in it or not, just delete them all)
Currently I use ls -1 -d */, and record them in a file, and do sed, and then run it. It rather long way. I'm looking for better way deleting only directories
To delete all directories and subdirectories and leave only files in the working directory, I have found this concise command works for me:
rm -r */
It makes use of bash wildcard */ where star followed by slash will match only directories and subdirectories.
find . -maxdepth 1 -mindepth 1 -type d
then
find . -maxdepth 1 -mindepth 1 -type d -exec rm -rf '{}' \;
To add an explanation:
find starts in the current directory due to . and stays within the current directory only with -maxdepth and -mindepth both set to 1. -type d tells find to only match on things that are directories.
find also has an -exec flag that can pass its results to another function, in this case rm. the '{}' \; is the way these results are passed. See this answer for a more complete explanation of what {} and \; do
First, run:
find /path -d -type d
to make sure the output looks sane, then:
find /path -d -type d -exec rm -rf '{}' \;
-type d looks only for directories, then -d makes sure to put child directories before the parent.
Simple way :-
rm -rf `ls -d */`
find command only (it support file deletion)\
find /path -depth -type d -delete
-type d looks only for directories, then -depth makes sure to put child directories before the parent. -delete removing filtered files/folders
In one line:
rm -R `ls -1 -d */`
(backquotes)
Does anyone have a good shell line for this?
I want to check the age on a directory. If I created multiple directories on a weekly basis and I want to purge them/delete them based on 7 days later for example.
How would I do that?
This will let you do a dry run, remove the echo if you like the output
find /path/to/toplevel -type d -mtime +7 -exec echo rm -rf {} +
Update
If you have an older version of find that doesn't comply with POSIX 2004 then use this instead:
find /path/to/toplevel -type d -mtime +7 -exec echo rm -rf {} \;
or
find /path/to/toplevel -type d -mtime +7 -print0 | xargs -0 echo rm -rf {}
The former terminated by \; will call rm for each directory it finds, the latter with xargs will attempt to call rm as few times as possible by passing multiple directories to a single call to rm and thus be much faster. The latter also has identical behavior to the first one terminated with a +