Find for YML and YAML files on bash find - bash

I am trying to find all .yaml and .yml
I tried
find . -name '*.{yml,yaml}' -exec echo "{}" \;
But no results
Neither in the following way
find . -name '*.yml' -name '*.yaml' -exec echo "{}" \;
Returns nothing.
Is it possible to use the find command to search for both extensions?

With GNU find find none or one a:
find . -regextype egrep -regex '.*ya?ml$'
or
find . -regextype egrep -regex '.*ya{0,1}ml$'
See: man find

Something like this.
find . \( -name '*.yaml' -o -name '*.yml' \)
See UsingFind
See Understanding-the-exec-option-of-find

Related

find and delete folder and/or zip file in a directory [duplicate]

I was trying to get a list of all python and html files in a directory with the command find Documents -name "*.{py,html}".
Then along came the man page:
Braces within the pattern (‘{}’) are not considered to be special (that is, find . -name 'foo{1,2}' matches a file named foo{1,2}, not the files foo1 and foo2.
As this is part of a pipe-chain, I'd like to be able to specify which extensions it matches at runtime (no hardcoding). If find just can't do it, a perl one-liner (or similar) would be fine.
Edit: The answer I eventually came up with include all sorts of crap, and is a bit long as well, so I posted it as an answer to the original itch I was trying to scratch. Feel free to hack that up if you have better solutions.
Use -o, which means "or":
find Documents \( -name "*.py" -o -name "*.html" \)
You'd need to build that command line programmatically, which isn't that easy.
Are you using bash (or Cygwin on Windows)? If you are, you should be able to do this:
ls **/*.py **/*.html
which might be easier to build programmatically.
Some editions of find, mostly on linux systems, possibly on others aswell support -regex and -regextype options, which finds files with names matching the regex.
for example
find . -regextype posix-egrep -regex ".*\.(py|html)$"
should do the trick in the above example.
However this is not a standard POSIX find function and is implementation dependent.
You could programmatically add more -name clauses, separated by -or:
find Documents \( -name "*.py" -or -name "*.html" \)
Or, go for a simple loop instead:
for F in Documents/*.{py,html}; do ...something with each '$F'... ; done
This will find all .c or .cpp files on linux
$ find . -name "*.c" -o -name "*.cpp"
You don't need the escaped parenthesis unless you are doing some additional mods. Here from the man page they are saying if the pattern matches, print it. Perhaps they are trying to control printing. In this case the -print acts as a conditional and becomes an "AND'd" conditional. It will prevent any .c files from being printed.
$ find . -name "*.c" -o -name "*.cpp" -print
But if you do like the original answer you can control the printing. This will find all .c files as well.
$ find . \( -name "*.c" -o -name "*.cpp" \) -print
One last example for all c/c++ source files
$ find . \( -name "*.c" -o -name "*.cpp" -o -name "*.h" -o -name "*.hpp" \) -print
I had a similar need. This worked for me:
find ../../ \( -iname 'tmp' -o -iname 'vendor' \) -prune -o \( -iname '*.*rb' -o -iname '*.rjs' \) -print
My default has been:
find -type f | egrep -i "*.java|*.css|*.cs|*.sql"
Like the less process intencive find execution by Brendan Long and Stephan202 et al.:
find Documents \( -name "*.py" -or -name "*.html" \)
Braces within the pattern \(\) is required for name pattern with or
find Documents -type f \( -name "*.py" -or -name "*.html" \)
While for the name pattern with and operator it is not required
find Documents -type f ! -name "*.py" -and ! -name "*.html"
#! /bin/bash
filetypes="*.py *.xml"
for type in $filetypes
do
find Documents -name "$type"
done
simple but works :)
I needed to remove all files in child dirs except for some files. The following worked for me (three patterns specified):
find . -depth -type f -not -name *.itp -and -not -name *ane.gro -and -not -name *.top -exec rm '{}' +
This works on AIX korn shell.
find *.cbl *.dms -prune -type f -mtime -1
This is looking for *.cbl or *.dms which are 1 day old, in current directory only, skipping the sub-directories.
find MyDir -iname "*.[j][p][g]"
+
find MyDir -iname "*.[b][m][p]"
=
find MyDir -iname "*.[jb][pm][gp]"
What about
ls {*.py,*.html}
It lists out all the files ending with .py or .html in their filenames

How to extract files with extension from directories?

I am currently extracting pictures from a large multi-levels directory using the following bash command:
find . -name \*.jpg -exec cp {} /newdir_path_.. \;
However, all pictures are stored under 3 versions:
xxx-LD.jpg
xxx-SD.jpg
xxx.jpg
I just want to extract the xxx.jpg pictures, not the LD and SD...
how should my command be modified to perform such extraction?
You can add more tests:
find . -name '*.jpg' -not -name '*-[LS]D.jpg' -exec cp {} /newdir_path_.. \;
-not is a GNU extension; you can use ! -name instead. In some shells, ! has to be escaped: \! -name.
This may also work for you considering your filenames only contain digits before .jpg:
find . -iregex '.*/[0-9]*\.jpg$' -exec cp {} /newdir_path_.. \;

Removing all the files with a specific extension using bash

I want to remove all the files with '*.tar.gz' extension using a bash command.
I tried the following, but it didn't work.
find . -iname '*.tar.gz' | rm
Could you please suggest which command should I use in this case?
Also, could you please tell me why the above command doesn't work?
find itself can delete in some versions, so :
find . -iname '*.tar.gz' -delete
if you don't have this switch, use anubhava's solution.
Don't pipe rm to output of find output, use xargs or find -exec:
find . -iname '*.tar.gz' -exec rm {} +
OR:
find . -iname '*.tar.gz' -print0 | xargs -0 -I {} rm {}

Bash/Shell Combine options using find

Using the find command is there a way to combine options:
i.e.
find . -type fd -name "somefile"
Although -type ignores the second option; I'm looking to find only files or directories.
You can use -o for OR condition in find:
find . \( -type d -o -type f \) -name "somefile"

Or condition in bash pattern

I'm searching some files with: find . -name "*.en.php" and find . -name "*.fr.php".
I want both commands in the same line, something like : find . -name "*.(en|fr).php" but it doesn't work.
Thanks in advance for your help.
EDIT
my command is like this : find . -not -path Config -name "*.fr.php", is there a solution do not repeat -not -path Config ?
Try:
find -name "*.en.php" -o -name "*.fr.php"
If you for example want to run command on each found file, than you need to additional ()
(this will count num of lines in all found files):
find \( -name "*.en.php" -o . -name "*.fr.php" \) -exec cat {} \; | wc -l
You should be able to combine expression with an or operator, thus:
find . -name '*.en.php' -o -name '*.fr.php' ...
You can see all the operators in the man page listed under OPERATORS (and, or, not, parentheses and so forth).
Use the find -o operator, eg.
find . -name "*.en.php" -o -name "*.fr.php"
Edit:
Like so:
find . -path './Config' -prune -o \( -name "*.en.php" -o -name "*.fr.php" \)
The default operator in find (if one is ommited) is and, the parentheses group the name expression. I've added -prune to prevent find from recursing into the Config directory.

Resources