How to pass regular expression to the command find in Linux? - regex

When I type command
find ./ -iname "*.pdf" or find ./ -iname \*.pdf
all pdf files under current folder tree are listed.
Similarly,
find ./ -iname "*.doc"
lists all the doc files.
My question is how to list both types of files? I tried commad like
find ./ -iname "*.{pdf,doc}"
But that does not work.

Using glob you can use -o (OR)`:
find . \( -iname "*.pdf" -o -iname "*.doc" \)
Or using regex:
find . -regextype posix-extended -regex '.*\.(pdf|doc)$'
On OSX find use:
find -E . -regex '.*\.(pdf|doc)$'

Related

find files matching several patterns in bash

I am trying to find all the files in a folder that ends with any of this expressions:
"00.png" or "25.png" or "50.png" or "75.png"
I am using the command
find . -type f -name '(*00.png|*25.png|*50.png|*75.png)'
with no success, what is the correct way to do it?
Without using any regex you can use:
find . -name '*[05]0.png' -o -name '*[27]5.png'
If you are really keen to use regex then use this gnu find command:
find . -regextype egrep -regex '.*/([05]0|[27]5)\.png$'
You can use regex option of find command :
find . -type f -regextype posix-extended -regex '(.*00\.png|.*25\.png|.*50\.png|.*75\.png)'

how to use find -regex ... what regex dialect is it?

I'm using this series of commands very often, to list all files but excluding sub-directories like .git and others,
find \( -name .git -or -name node_modules \) -prune -or -ls
depends on different project's structure, might have more <unwanted-dir>
find \( -name .git -or -name node_modules -or -name another-unwanted-dir \) -prune -or -ls
want to merge into a single regex, like
find -regex './(.git|node_modules)' -prune -or -ls
but this does not work, have tried -regextype posix or other types, but haven't figured out one working
Update: this one indeed works, I found the reason is the -regextype has to be given before -regex
find -regextype posix-egrep -regex './(.git|node_modules|another-dir)' -prune -or -ls
not after: this one is not working
find -regex './(.git|node_modules|another-dir)' -regextype posix-egrep -prune -or -ls
But, what is the default regextype ? Can anyone make a regex work without specifying regextype ? (to make the command length shorter...)

find - all .a files except .dll.a files

I'm using "find" on Ubuntu to delete some files.
find -iname "*.a" -delete
deletes all .a files. But I want to keep .dll.a files. Using -regex ".*^(?!dll).a" fails with "Invalid preceding regular expression".
For testing, I use these 4 filenames:
libz.a, libz.dll.a, libintl.a, libintl.dll.a
Try this:
rm `find . -type f -name "*.a" | grep -v "dll.a"`

How to use find and the prune option with an while loop

i've got an question about find, prune and print combined with an while loop. I want find every file named trace but not the files ending on mailed. Also i want to exclude the files in the lost+found directory. My idea was to use the following command:
find /opt/myTESTdir/ -iwholename '*lost+found' -prune -o -ctime +4 -type f -iname "*trace*" -not -iname "*.mailed*" -print0 | while read file ; do newfile=${file%.txt}".mailed" ; mv -v $file $newfile ; done
My question is now should this work or is there an syntax error? I've tried out the find command without everything behind the pipe and it seems, that's work correctly. But i'm not sure about the combination. I hope you could answer me :)
(Sorry for my bad english)
In while loop, it seems you are trying to rename files with extension .txt to .mailed. You can achieve the same using -exec option.
Try adding following portion to the end of your find command and remove piping to while loop.
-exec sh -c 'mv -f $0 ${0%.txt}.mailed' {} \;
Complete command would look like
find /opt/myTESTdir/ -iwholename '*lost+found' -prune -o -ctime +4 -type f -iname '*trace*' ! -iname '*.mailed*' -exec sh -c 'mv -f $0 ${0%.txt}.mailed' {} \;

Find & replace recursively except for certain files

With regards to this post, how would I exclude one or more files from applying the string replacement? By using the aforementioned post as an example, I would like to be able to replace "apples" with "oranges" in all descendant files of a given directory except, say, ./fpd/font/symbol.php.
My idea was using the -regex switch in the find command but unfortunately it does not have a -v option like the grep command hence I can't negate the regex to not match the files where the replacement must occur.
I use this in my Git repository:
grep -ilr orange . | grep -v ".git" | grep -e "\\.php$" | xargs sed -i s/orange/apple/g {}
It will:
Run find and replace only in files that actually have the word to be replaced;
Not process the .git folder;
Process only .php files.
Needless to say you can include as many grep layers you want to filter the list that is being passed to xargs.
Known issues:
At least in my Windows environment it fails to open files that have spaces in the path or name. Never figured that one out. If anyone has an idea of how to fix this I would like to know.
Haven't tested this but it should work:
find . -path ./fpd/font/symbol.php -prune -o -exec sed -i 's/apple/orange/g' {} \;
You can negate with ! (or -not) combined with -name:
$ find .
.
./a
./a/b.txt
./b
./b/a.txt
$ find . -name \*a\* -print
./a
./b/a.txt
$ find . ! -name \*a\* -print
.
./a/b.txt
./b
$ find . -not -name \*a\* -print
.
./a/b.txt
./b