Find with or operators - linux

I've a bash command who should find and remove files:
/usr/bin/find /srv/www/vest2/produktion/ -type f \( -iname 'vest*.xml' -o -iname 'vest*.xls'-o -iname 'vwk*.xls' \) -ctime +90 -exec rm {} \ ';'
but it doesn't work.
Whats the problem?
Many thanks
Martin

Remove the single quotes around the final semi colon
Before:
/usr/bin/find /srv/www/vest2/produktion/ -type f \( -iname 'vest*.xml' -o -iname 'vest*.xls'-o -iname 'vwk*.xls' \) -ctime +90 -exec rm {} \ ';'
/usr/bin/find: missing argument to `-exec'
Now:
/usr/bin/find /srv/www/vest2/produktion/ -type f \( -iname 'vest*.xml' -o -iname 'vest*.xls'-o -iname 'vwk*.xls' \) -ctime +90 -exec rm {} \;
/usr/bin/find: `/srv/www/vest2/produktion/': No such file or directory
If that directory existed for me, it would have executed.

Related

-exec option of the find command does not work as expected on Ubuntu

I am doing some practice on find command but I don't get the expected result when I attempt to use -execoption of it. The command I wrote just works without -exec option as the following:
$ find ~ \( -type f -not -perm 0600 \) -or \( -type d -name 'D*' \)
/home/baki/.bashrc
/home/baki/.bash_logout
/home/baki/.cache/motd.legal-displayed
/home/baki/.config/wslu/baseexec
/home/baki/.config/wslu/oemcp
/home/baki/.gitconfig
/home/baki/.landscape/sysinfo.log
/home/baki/.motd_shown
/home/baki/.profile
/home/baki/.ssh/known_hosts
/home/baki/.sudo_as_admin_successful
/home/baki/ssh_start
/home/baki/token
However, when I add the -exec option to the end of the command, it doesn't give any output:
find ~ \( -type f -not -perm 0600 \) -or \( -type d -name 'D*' \) -exec ls -l '{}' ';'
I have searched about it but I couldn't find a piece of useful information that can solve my problem.
Is my command wrong or is it about something else?
Thank you for your help.
The default -and operation has higher precedence than -or. Use extra parentheses:
find ~ \( \( -type f -not -perm 0600 \) -or \( -type d -name 'D*' \) \) -exec ls -l '{}' ';'
You can probably omit the inner parentheses in this case.

Deleting a file inside a directory with excluding a folder inside

I have a folder structure like below. I am deleting all files inside /data/mydata/ which are older than 2 hrs using the command below, but I want to exclude the metadata folder. How can I do it?
Command:
/usr/bin/find /data/mydata -mindepth 1 -type d -empty -delete -o -cmin +120 -type f -delete
Directory structure:
/data/mydata/
--test1
--f2.txt
--foo
--metadata
--test1.json
--test2
--metadata
--foo(under metadata)
--test2.json
--f2.txt
To exclude a particular path, you can do:
/usr/bin/find /data/mydata -path /data/mydata/test2/metadata -prune \
-o -mindepth 1 \( \( -type d -empty \) -o \( -cmin +120 -type f \) \) -delete
To exclude all instances of directories named metadata, you probably want:
/usr/bin/find /data/mydata -name metadata -prune \
-o -mindepth 1 \( \( -type d -empty \) -o \
\( -cmin +120 -type f \) \) -delete

How to remove files without certain extension?

How to remove all files without the .txt and .exe extensions recursively in the current working directory? I need a one-liner.
I tried:
find . ! -name "*.txt" "*.exe" -exec rm -r {} \
find -type f -regextype posix-extended -iregex '.*\.(txt|exe)$'
Try this.
find . -type f ! -name "*.exe" ! -name "*.txt" -exec rm {} \;
The above command will remove all the files other than the .exe and .txt extension files in the current directory and sub directory recursively.
If you have GNU find with the -delete action:
find . -type f ! \( -name '*.txt' -o -name '*.exe' \) -delete
And if not:
find . -type f ! \( -name '*.txt' -o -name '*.exe' \) -exec rm -f {} +
using -exec ... {} + to execute rm as few times as possible, with the arguments chained.
Try the following:
rm -f $(find . -type f ! \( -name "*.txt" -o -name "*.exe" \))
This will first recursively find all files that do not end with .txt or .exe extensions, and then delete all of these files.

FInd patternf for multiple pattern of files

I need to search for multiple pattern of files and check their mtime and if it morethan 30 days then delete all the files. I am using the below command but it's deleting only one pattern of file and not all. Kindly let me know where is the mistake in my command.
find /root -type f \( -name "*.tgz" -o -name "*.bz2" \) -mtime +30 -print -exec rm '{}' +
Try escaping parentheses in the command and adding a wildcard character:
find /root -type f \( -name "*.tgz" -o -name "*.bz2" \) -mtime +30 -exec rm {} \+

find command search only non hidden directories

In the following command i want to search only only the directories which are non hidden how can i do this using the following command .Iwant to ignore hidden directories while searching the log file
find /home/tom/project/ -name '.log.txt'
ls /home/tom/project/
dir1
dir2
.backup
.snapshot/
.ignore/
Try
find /home/tom/project -type d -name '.*' -prune -o -name .log.txt -print
This will find all files but ignore those that start with a dot so hidden files.
find /home/tom/project/ -type f \( -iname ".log.txt" ! -iname ".*" \)
EDIT:
If the above those not work, this should do the trick. It has a better regex.
find /home/tom/project/ \( ! -regex '.*/\..*' \) -type f -name ".log.txt"
EDIT2:
The following will exclude hidden folders but will search for the hidden files that have the requested pattern:
find /home/tom/project/ \( ! -regex '.*/\..*/..*' \) -type f -name ".log.txt"
EDIT3:
The grep solution :) if this doesn't work i'm lost :)
find /home/tom/project/ \( ! -regex '.*/\..*/..*' \) -exec grep -l ".log.txt" {} \;
EDIT4:
Have you tried the simple solutions?
find /home/tom/project/ -type f -name ".log.txt"
OR
find /home/tom/project/ -type f -name "*" -exec grep -l ".log.txt" {} \;

Resources