I am honestly nowhere near to be a decent bash scripter, but I made a little research and found a command that seems to be useful
find /path/to/files* -mtime +1 -exec rm {} \;
The question is if this line will remove directories? Because I want to only remove files that are images (actually in a *.jpeg format)
No, rm without the -r flag does not remove directories.
It looks like you want to add some more filters:
-type f to match only files
-name '*.jpeg' to match only files ending with .jpeg
Lastly, instead of -exec rm {} \;, you could use the much simpler -delete.
Putting it together, this looks more appropriate for you:
find /path/to/files* -mtime +1 -type f -name '*.jpeg' -delete
Then narrow your search results to *.jpeg files:
find /path/to/files* -mtime +1 -type f -name "*.jpeg" -exec rm {} \;
It's always better to remove the exec parameter to do a dry run before delete:
find /path/to/files* -mtime +1 -type f -name "*.jpeg"
Each line will be passed to rm command, and nothing more.
Related
I have a dir that is full of many htm reports that I keep around for 30 days and delete old ones via a cron, but there is one sub-dir I would like to keep longer. So this is the line I made in the cron, but how do I tell it to leave one sub-dir alone.
5 0 * * * find /var/www -name "*.htm*" -type f -mtime +30 -exec rm -f {} \;
Any help is greatly appreciated!
Use -prune to prevent going into a directory that matches some conditions.
find /var/www -type d -name 'excluded-directory' -prune -o -name "*.htm*" -type f -mtime +30 -exec rm -f {} \;
In addition to suggestion below, suggesting to use full path in cron.
Also to use find option -delete in-place of -exec rm -f {} \;. It is somewhat safer.
-delete
Delete found files and/or directories. Always returns true.
This executes from the current working directory as find recurses
down the tree. It will not attempt to delete a filename with a
"/" character in its pathname relative to "." for security
reasons. Depth-first traversal processing is implied by this
option. The -delete primary will fail to delete a directory if
it is not empty. Following symlinks is incompatible with this
option.
5 0 * * * /usr/bin/find /var/www -type d -name 'excluded-directory' -prune -o -name "*.htm*" -type f -mtime +30 -delete
I was writing a bash script that finds and deletes the .blend1 and .blend2 files that blender creates as you edit and save .blend files. It contains lines in pairs like this:
find Documents -name "*.blend1" -exec rm -rf {} \;
find Documents -name "*.blend2" -exec rm -rf {} \;
This works just fine, though I was curious if it is at all possible to combine those two find commands some way, so that it would be just one command that finds and deletes both .blend1 and .blend2 files.
Not super-important, I'd just prefer it if my script were a little more compact.
find Documents -name '*.blend[12]' -delete
(-delete is a GNU find extension.)
Other ways:
find Documents '(' -name '*.blend1' -o -name '*.blend2' ')' -delete
find Documents -name '*.blend*' -delete
Here's another way...
find Documents -name '*.blend[12]' -exec rm -rf {} \;
Yes you can use regex to match more that one patterns into one:
find Documents -regextype posix-egrep -regex '.*\.(blend1|blend2)$' -exec rm -rf {} \;
Or with newer find versions:
find Documents -regextype posix-egrep -regex '.*\.(blend1|blend2)$' -delete
Without regex you can do:
find Documents \( -name "*.blend1" -o -name "*.blend2" \) -delete
I need to remove any file in the directory that is older than 2 years old. It is very important that I keep the newest files and delete the old files.
I have searched and found this.
find /path/to/files* -mtime +365 -exec rm {} \;
Can I just multiply the number?
find /path/to/files* -mtime +1095 -exec rm {} \;
Is there a way to add a switch that will print the file name to the screen as it removes it? To make sure it is doing what I am expecting?
I have also found this:
find /rec -mtime +365 -print0 | xargs -0 rm -f
Is there a major difference between the two? Is one better than the other? What I have read says that xargs is faster. Would I be able to multiply the mtime number out to a 2nd or 3rd year?
And finally would would I be able to place the code as it is into a cron job that can run daily?
Thank you!
Can I just multiply the number?
find /path/to/files -mtime +1095 -exec rm {} \;
Yes. And to "echo" before you remove
find /path/to/files -mtime +1095 -print
Then the version with -exec rm {} \; to remove the files (when you are ready).
find /path/to/files* -mtime +1095 -exec rm {} \;
That should work fine, you can run a dry a run of this by simply listing the files that are found by the command:
find /path/to/files* -mtime +1095 -exec ls {} \;
To be safe though I would also add in a -type to ensure that other things dont get deleted:
find /path/to/files* -type f -mtime +1095 -exec rm {} \;
To answer the second part of your question.
Yes there is a major difference in using -exec or xargs.
-exec starts a new process of rm for every file found. This creates a lot of overhead and can seriously slow down Systems if you delete a lot of files.
xargs creates only as much rm processes as needed, as it creates a command line containing as much files as possible. So only a few rm processes are created.
But both are better than -delete, because delete is unsave
I am able to delete lets say all regular files in a folder older than 7 days via:
find /path/to/dir -type f -mtime +7 -exec rm {} \;
with a single problem. There is a file here (.gitignore) which I want to keep. I tried using regex but apparently findutils regex does not have support for negative lookahead (?!gitignore)
Any other ideas?
Use ! -name .gitignore
find /path/to/dir ! -name .gitignore -type f -mtime +7 -exec rm {} \;
You can group multiple arguments within escaped parentheses. Example, to remove all files except .gitignore and javascript files (ending in .js):
find /path/to/dir ! \( -name ".gitignore" -o -name "*.js" \) -type f -mtime +7 -exec rm {} \;
-o means or
Is there a way to write the file names to a file before they are deleted for reference later to check what has been deleted.
find <PATH> -type f -name "<filePattern>" -mtime +1 -delete
Just add a -print expression to the invocation of find:
find <PATH> -type f -name "<filePattern>" -mtime +1 -delete -print > log
I'm not sure if this prints the name before or after the file is unlinked, but it should not matter. I suspect -delete -print unlinks before it prints, while -print -delete will print before it unlinks.
Like William said, you can use -print. However, instead of -print > log, you can also use the -fprint flag.
You'd want something like:
find <PATH> -type f -name "<filePattern>" -mtime +1 -fprint "<pathToLog>" -delete
For instance, I use this in a script:
find . -type d -name .~tmp~ -fprint /var/log/rsync-index-removal.log -delete
You can use -exec and rm -v:
find <PATH> -type f -name "<filePattern>" -mtime +1 -exec rm -v {} \;
rm -v will report what it is deleting.
With something like this you can execute multiple commands in the exec statement, like log to file, rm file, and whatever more you should need
find <PATH> -type f -name "<filePattern>" -mtime +1 -exec sh -c "echo {} >>mylog; rm -f {}" \;
From a shell script named removelogs.sh
run the command sh removelogs.sh in terminal
this is the text in removelogs.sh file.
cd /var/log;
date >> /var/log/removedlogs.txt;
find . -maxdepth 4 -type f -name \*log.old -delete -print >> /var/log/removedlogs.txt
. - to run at this location !!! so ensure you do not run this in root folder!!!
-maxdepth - to prevent it getting out of control
-type - to ensure just files
-name - to ensure just your filtered names
-print - to send the result to stdout
-delete - to delete said files
>> - appends to files not overwrites > creates new file
works for me on CENTOS7