linux find prune - string

I am trying to exclude two directories; vntvdone and downloading, but for some reason, my command still goes in there and outputs the file within it:
find -name '*.avi' -o -name '*.mkv' -o -name '*.mp4' -o -name '*.VOB' -o -path './downloading' -prune -o -path './vntvdone' -prune
I am also running into problems where if a folder/directory that has .mp4 in it, it also gets treated as a file as well... how can we do this search only for files and not folders?

I find it easier to use ! than use prune. I've assumed the starting path for find is '.' The example omits it.
find . \( -type d -a ! -name 'downloading' -a ! -name 'vntdone' -a ! -name '.' \) -o -name \*.avi -o -name \*.mkv -o -name \*.mp4 -o -name \*.VOB

Related

Linux Find command- exclude find based on file name

I feel like this is a ridiculously easy question but I cannot find a simple regex answer for this. Basically, I am trying to use find to get a list of all files in my system with some exclusions. One of these exclusions is any file that ends in .Foo.cs, or any file named FooInfo.cs. I have successfully excluded a couple directories from my search, but cannot seem to exclude these two files. I've tried using -name, but would -name even work for this? Below is my expression. Thanks.
find . ! -name 'FooInfo.cs' ! -name '*.Foo.cs' -type d \( -name Foo-o -name 2Foo -o -name 2_Foo \) -prune -o -type f ! -size 0 \( -name "*.java" -o -name "*.cs" -o -name "*.cpp" -o -name "*.cxx" -o -name "*.cc" -o -name "*.c" -o -name "*.h" -o -name "*.scala" -o -name "*.css" -o -name "*.html" -o -name "*.bat" -o -name "*.js" \) -exec realpath {} \;| xargs grep -L CUSTOMERINFO | sed -e 's/$/\r/g' >> ../output.txt
So I'm not sure why, but I ended up fixing this by changing the order of what I'm excluding. Instead of excluding at the very beginning, the following worked (moving the ! -name '.FOO.cs' and ! -name '.fooinfo.cs' to right after the declaration type -f).
I'm assuming this worked because they are files so they must be flagged with type -f. But please comment and correct below if you know why.
find . -type d \( -name Foo-o -name 2Foo -o -name 2_Foo \) -prune -o -type f ! -size 0 ! -name 'FooInfo.cs' ! -name '*.Foo.cs' \( -name "*.java" -o -name "*.cs" -o -name "*.cpp" -o -name "*.cxx" -o -name "*.cc" -o -name "*.c" -o -name "*.h" -o -name "*.scala" -o -name "*.css" -o -name "*.html" -o -name "*.bat" -o -name "*.js" \) -exec realpath {} \;| xargs grep -L CUSTOMERINFO | sed -e 's/$/\r/g' >> ../output.txt

Find Command with multiple file extensions

I'm looking through many sub directories and finding all the files ending in .JPG .jpg and .png and copying them to a separate directory, however just now its only finding .JPG
Could someone explain what i'm doing wrong?
find /root/TEST/Images -name '*.png' -o -name '*.jpg' -o -name '*.JPG' -exec cp -t /root/TEST/CopiedImages {} +
You have to group the -o conditions because -a, the implied AND between the last -name '*.JPG' and -exec has higher precedence:
find /root/TEST/Images \( -name '*.png' -o -name '*.jpg' -o -name '*.JPG' \) -exec cp -t /root/TEST/CopiedImages {} +
Grouping is done with parentheses, but they have to be escaped (or quoted) due to their special meaning is shell.
Unrelated to this, you can shorten the overall expression by combining filters for jpg and JPG with the case-insensitive -iname (as noted in comments):
find /root/TEST/Images \( -name '*.png' -o -iname '*.jpg' \) -exec cp -t /root/TEST/CopiedImages {} +

Find especific directory and ignore other

I need to find all the iplanets on one server and I was thinking to use this command:
find / type d -name https-* | uniq
But at the same time I need to ignore some directories/file. I've been trying to use !, but it not always work. I have a command like this:
find / type d -name https-* ! -name https-admserv* ! -name conf_bk* ! -name alias* ! -name *db* ! -name ClassCache* | uniq
I need to ignore all that. The directories admserv, conf_bk, alias and tmp and the files *.db*
Basically I need find this:
/opt/mw/iplanet/https-daniel.com
/opt/https-daniel1.com
/apps/https-daniel2.com
I only need to find the directory name. How can I ignore all the other stuff?
Use -prune to keep from recursing into directories:
find / \( -type d \( -name 'https-admserv*' -o -name 'conf_bk*' -o -name 'alias*' -o -name 'tmp' \) -prune -o -type d -name 'https-*' -print
There's no need to ignore any files. You're only selecting https-* directories, so everything else is ignored.
And there's no need to pipe to uniq, since find never produces duplicates.

How can I make find pass file names to exec without the leading directory name?

Someone created directories with names like source.c. I am doing a find over all the directories in a tree. I do want find to search in the source.c directory, but I do not want source.c to be passed to the grep I am doing on what is found.
How can I make find not pass directory names to grep? Here is what my command line looks like:
find sources* \( -name "*.h" -o -name "*.cpp" -o -name "*.c" \) -exec grep -Hi -e "ThingToFind" {} \;
Add -a -type f to your find command. This will force find to only output files, not directories. (It will still search directories):
find sources* \( -name "*.h" -o -name "*.cpp" -o -name "*.c" \) -a -type f -exec grep -Hi -e "ThingToFind" {} \;

find all but skip one folder

I have a command that looks through all my sub folders for files, however I want it to skip a folder from the search and I'm not sure what is the right way to do this:
find -name '*.avi' -o -name '*.mkv' -o -name '*.mp4' -o -name '*.vob'
I want it to not look into the folder name: secure
I tried:
find -name '*.avi' -o -name '*.mkv' -o -name '*.mp4' -o -name '*.vob' --skip 'secure'
but it does not work.
Thanks for your help in advance.
There is no --skip argument in GNU find. But you can do what you want using the -path and -prune expressions. The syntax is a little weird: you use -path ./secure -prune as a term which you then OR with the rest of the expression. So in your case:
find . -name '*.avi' -o [...] -o -path ./secure -prune
Note that this will still return the directory ./secure in the results, but nothing inside it.
What about the following?
find \( -name '*.avi' -o -name '*.mkv' -o -name '*.mp4' -o -name '*.vob' \) -a -not -path './secure*'

Resources