How can I recursively find all files in current and subfolders based on wildcard matching?
-
Does this answer your question? [Find all files with a filename beginning with a specified string?](https://stackoverflow.com/questions/4034896/find-all-files-with-a-filename-beginning-with-a-specified-string) – Josh Correia Oct 20 '20 at 20:49
17 Answers
Use find for that:
find . -name "foo*"
find
needs a starting point, and the .
(dot) points to the current directory.
- 75,045
- 15
- 108
- 99
-
25I know this is tagged as linux but this is worth mentioning: the path is required for on other *nix variants that aren't linux. On linux, the path is optional if you want to use dot. – IslandCow Nov 16 '13 at 00:14
-
-
4@Seatter "foo*" tells find to look for all files that start with "foo". It is just his example. You could use "gpio*" to find all files who's names start with gpio, or just "gpio1" to find all files named gpio1. – schumacher574 Apr 02 '14 at 18:00
-
* is a wildcard - more wildcard possibilities here: http://www.tldp.org/LDP/GNU-Linux-Tools-Summary/html/x11655.htm – Michael Apr 30 '14 at 10:29
-
38note that the "foo*" is in quotes so the shell doesn't expand it before passing it to find. if you just did `find . foo*`, the `foo*` would be expanded AND THEN passed to find. – grinch May 19 '14 at 14:29
-
3
-
I have a file test.xml in the subdirectory of my current working directory and I have used the command find . -name "test*". It doesnt work. – Atom Nov 12 '15 at 00:46
-
1For some reason it doesn't work when put in a sh script. Does it need bash or something? – Howie Feb 18 '16 at 13:54
-
49Worth stressing that `" "` is very necessary for recursive searching. – WesternGun Oct 21 '16 at 11:43
-
12Also useful: If you don't want to be notified about directories you don't have permission to (or other errors), you can do `find . -name "foo*" 2>/dev/null` – Jobbo Aug 15 '17 at 10:54
-
If you wish to ignore case (as in most cases when I use this) then you could do: find . -iname "foo*" – Orn Arnarson Mar 19 '18 at 18:10
-
In reponse to @IslandCow's comment: that's not true (at least not everywhere). I have to use '.' explicitly on my Fedora boxes. – Clearer Mar 29 '18 at 13:31
-
2@WesternGun Can you explain why the `" "` is needed? What is "expansion" and why is that bad? – Kolob Canyon May 10 '18 at 17:49
-
2@KolobCanyon you can check the man page of find, or [this link](https://linux.die.net/man/1/find) and search the word "non-bug" and then "quote", there you have more info. Also, check [this](http://linuxcommand.org/lc3_lts0080.php). Generally, `*` expansion is "iterate current dir and substitute the * with every file name". So, to avoid this, we use quotes. – WesternGun May 11 '18 at 06:44
-
@WesternGun Is that different than string interpolation? Because I thought quotes meant string interpolation in the shell – Kolob Canyon May 11 '18 at 15:11
-
1@KolobCanyon something like that, but the links have more and I think expansion is broader. – WesternGun May 11 '18 at 15:31
-
Is it possible to group the results by directories? Instead of showing every file, I would like to see the locations of such files. – NurShomik Jun 22 '18 at 21:56
-
This is ridiculous... what if I only want to search in the current dir?? – Yan King Yin Feb 17 '19 at 04:08
-
-
weirdly enough this doesn't work me. What worked for me is the answer from Paul Whipp – metafa May 27 '19 at 14:26
-
If I leave out the quotes, it searches only in the current directory. The genius designer of this should explain the behavior. – Yan King Yin Aug 25 '19 at 12:25
-
dot does not work for me, I have to use `find /some/path/ -iname "foo*"` – andrej Aug 17 '20 at 13:07
Piping find into grep is often more convenient; it gives you the full power of regular expressions for arbitrary wildcard matching.
For example, to find all files with case insensitive string "foo" in the filename:
~$ find . -print | grep -i foo
- 81,480
- 12
- 93
- 144
- 13,812
- 4
- 37
- 47
-
76`find` also has the `-iname`, `-regex`, and `-iregex` flags for case-insensitive wildcard, regex, and case-insensitive regex matching, so piping to `grep` is unnecessary. – iobender Aug 04 '15 at 16:54
-
9I don't think it is about being unnecessary, but being more convenient. – Elijah Lynn Feb 08 '17 at 16:57
-
3However, piping to grep -v can allow you to use simple strings or regexes to remove entries you don't want. – door_number_three Apr 06 '17 at 03:15
-
5@iobender - Sadly, I can tell you from experience that not all systems come with a `find` command that supports those options. Sometimes `grep` becomes the only option. – Mr. Llama Jul 05 '18 at 17:36
find
will find all files that match a pattern:
find . -name "*foo"
However, if you want a picture:
tree -P "*foo"
Hope this helps!
- 150,910
- 39
- 198
- 279
- 2,828
- 3
- 16
- 24
-
21
-
1Tested on macOS Sierra, just add '--print' -> ' find . name "*foo" --print ' . http://superuser.com/questions/177289/searching-mac-through-terminal – john-salib Feb 09 '17 at 14:24
-
3
fd
In case, find
is too slow, try fd
utility - a simple and fast alternative to find
written in Rust.
Syntax:
fd PATTERN
Demo:
Homepage: https://github.com/sharkdp/fd
- 118,428
- 63
- 588
- 624
-
41
-
2Those performance results look very promising. You might consider adding fd to home-brew... – Gr3go Jan 11 '19 at 21:17
-
-
2@aprodan The demo image was copied from GitHub, but I believe they're using [`asciinema`](https://asciinema.org/), then converted to GIF format, but I'm not sure. – kenorb Feb 11 '19 at 23:38
-
1Actually it's SVG format, so probably [`asciicast2vector`](https://github.com/misc0110/asciicast2vector) can be used. – kenorb Feb 12 '19 at 23:57
-
find -L . -name "foo*"
In a few cases, I have needed the -L parameter to handle symbolic directory links. By default symbolic links are ignored. In those cases it was quite confusing as I would change directory to a sub-directory and see the file matching the pattern but find would not return the filename. Using -L solves that issue. The symbolic link options for find are -P -L -H
- 816
- 8
- 11
-
2L switch is very helpful. Many times user do not have any idea about underlying directories, whether they are softlinked or are normal directories. So in case of doubt, it always good to use L option. At least, it has always helped me. – Ritesh Jan 03 '18 at 16:21
-
2
If your shell supports a new globbing option (can be enabled by: shopt -s globstar
), you can use:
echo **/*foo*
to find any files or folders recursively. This is supported by Bash 4, zsh and similar shells.
Personally I've got this shell function defined:
f() { find . -name "*$1*"; }
Note: Above line can be pasted directly to shell or added into your user's ~/.bashrc
file.
Then I can look for any files by typing:
f some_name
Alternatively you can use a fd
utility with a simple syntax, e.g. fd pattern
.
- 118,428
- 63
- 588
- 624
-
1This just goes into a single level. Not recursing into the sub directories for me – Broncha Jun 07 '17 at 16:29
-
3@Broncha Because you need to activate the extended globbing by `shopt -s globstar` command. This is supported in Bash, zsh and similar shells. – kenorb Jun 07 '17 at 16:30
-
`bash-3.2$ shopt -s globstar` gives `bash: shopt: globstar: invalid shell option name` – drewish Oct 17 '17 at 05:09
-
find <directory_path> -type f -name "<wildcard-match>"
In the wildcard-match you can provide the string you wish to match e.g. *.c (for all c files)
- 2,527
- 5
- 23
- 32
-
2Your answer is the first most correct here as it only searches files as specified. The others not specifying type will return directories. – wilsotc Nov 23 '17 at 01:15
-
if you wish to search for a directory "-type f" could be changed to "-type d " – XYZ_Linux Sep 11 '19 at 07:02
You can use:
# find . -type f -name 'text_for_search'
If you want use REGX use -iname
# find . -type f -iname 'text_for_search'
- 33,075
- 16
- 78
- 86
- 131
- 1
- 3
Following command will list down all the files having exact name "pattern" (for example) in current and its sub folders.
find ./ -name "pattern"
- 989
- 11
- 19
for file search
find / -xdev -name settings.xml
--> whole computer
find ./ -xdev -name settings.xml
--> current directory & its sub directory
for files with extension type
find . -type f -name "*.iso"
- 143
- 2
- 6
Default way to search for recursive file, and available in most cases is
find . -name "filepattern"
It starts recursive traversing for filename or pattern from within current directory where you are positioned. With find command, you can use wildcards, and various switches, to see full list of options, type
man find
or if man pages aren't available at your system
find --help
However, there are more modern and faster tools then find, which are traversing your whole filesystem and indexing your files, one such common tool is locate or slocate/mlocate, you should check manual of your OS on how to install it, and once it's installed it needs to initiate database, if install script don't do it for you, it can be done manually by typing
sudo updatedb
And, to use it to look for some particular file type
locate filename
Or, to look for filename or patter from within current directory, you can type:
pwd | xargs -n 1 -I {} locate "filepattern"
It will look through its database of files and quickly print out path names that match pattern that you have typed.
To see full list of locate's options, type:
locate --help
or man locate
Additionally you can configure locate to update it's database on scheduled times via cron job, so sample cron which updates db at 1AM would look like:
0 1 * * * updatedb
These cron jobs need to be configured by root, since updatedb needs root privilege to traverse whole filesystem.
- 2,463
- 1
- 25
- 30
Use
find path/to/dir -name "*.ext1" -o -name "*.ext2"
Explanation
- The first parameter is the directory you want to search.
- By default
find
does recursion. - The
-o
stands for-or
. So above means search for this wildcard OR this one. If you have only one pattern then no need for-o
. - The quotes around the wildcard pattern are required.
- 47,549
- 10
- 193
- 157
I am surprised to see that locate is not used heavily when we are to go recursively.
I would first do a locate "$PWD" to get the list of files in the current folder of interest, and then run greps on them as I please.
locate "$PWD" | grep -P <pattern>
Of course, this is assuming that the updatedb is done and the index is updated periodically. This is much faster way to find files than to run a find and asking it go down the tree. Mentioning this for completeness. Nothing against using find, if the tree is not very heavy.
- 489
- 5
- 8
-
1`locate "$PWD*.mp4"` Just to remind that you may be able to skip the `grep` – Jefferey Cave May 14 '20 at 22:37
If you want to search special file with wildcard, you can used following code:
find . -type f -name "*.conf"
Suppose, you want to search every .conf files from here:
.
means search started from here (current place)
-type
means type of search item that here is file (f).
-name
means you want to search files with *.conf names.
- 218
- 2
- 11
Below command helps to search for any files
1) Irrespective of case
2) Result Excluding folders without permission
3) Searching from the root or from the path you like. Change / with the path you prefer.
Syntax :
find -iname '' 2>&1 | grep -v "Permission denied"
Example
find / -iname 'C*.xml' 2>&1 | grep -v "Permission denied"
find / -iname '*C*.xml' 2>&1 | grep -v "Permission denied"
- 404
- 1
- 7
- 16
-
1why on earth do you use grep for that? Just redirect stderr to null `find / -iname '*C*.xml' 2>/dev/null` – phuclv Mar 23 '19 at 05:51
This will search all the related files in current and sub directories, calculating their line count separately as well as totally:
find . -name "*.wanted" | xargs wc -l
- 131
- 1
- 3