Delete files in dir but exclude 1 subdir - linux

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

Related

Delete files older than 30 days, but in 1 directory the retention 6 months

I'd like to create a find which delete a files older than 30 days, but I have 1 directory where the retention should be 6 months.
How would that be possible?
This one would delete all files in all subdirectories which is older than 30 days if I'm correct.
/bin/find /root/script/* -type f -ctime +30 -exec rm {} \;
Bu how I can set that this directory needs different retention:
/root/script/owner
You can exclude the /root/script/owner from the find output using -path or -regex, combined with '!' to negate the test
find /root/script -type f -ctime +30 '!' -path '/root/script/owner/*' -exec rm {} \;
OR
find /root/script -type f -ctime +30 '!' -regex '/root/script/owner/.*' -exec rm {} \;
Then execute the custom delete on the special folder
find /root/script/owner -type f -ctime +180 -exec rm {} \;
You can combine multiple operators so that they restrict what is included. You actually already do this because you have a -type and -ctime, joined with an implicit AND.
The one you need to add is regex, and you can do something like:
/bin/find /root/script/* -type f ! -regex '/root/script/owner/.*' -ctime +30 -exec rm {} \;
This should exclude files in that particular tree since the ! -regex will be false for them. The basic idea is that only those that pass all the conditions will be subject to further operations.
In this case, any non-regular files will be excluded. Of the others, any that don't match the regex will be excluded. Of those remaining ones, we'll throw away any that don't match the 30-day requirement. Whatever's left will be actioned by the rm.
The remaining directory, of course, is done with the greater time:
/bin/find /root/script/owner -type f -ctime +186 -exec rm {} \;

Remove files in subdirectories older than 1 day with Linux command

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.

Remove all files under cache directory using find

I'm trying to use find to remove all files under cache directories in a web hosted environment.
find /home/hosted -maxdepth 2 -type d -name "cache" -print -exec rm -rf "{}/*" \;
I've tried several variations of this, but for some reason find won't remove the cache/* files. Anyone see anything I'm missing?
Thanks
Arguments for -exec don't get expanded as you expect. That is because -exec calls execve() directly and thus * does not get expanded to all files in a matching directory. If you want to have shell expansion, you have to feed -exec with /bin/sh (or a shell of your choice), like this:
find /your/dir -name "cache" -type d -maxdepth 2 -print -exec sh -c "rm -f {}/*" \;

Linux: Delete every file older than a date with one exceptional file

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

Linux find and delete files but redirect file names to be deleted

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

Resources