- How can I recursively find all files in current and subfolders based on wildcard matching?
- fd
- How to Recursively Find all Files in Current and Subfolders Based on Wildcard Matching in Linux
- What are Wild Cards
- Types of Wild Cards
- Recursively Find all Files in Current and Subfolders Based on Wildcard Matching
- 1: Finding Files Using Asterisk (*) Wildcard
- 2: Finding Files Using Question mark (?) Wildcard
- Finding Files Using tree Command
- Conclusion
- About the author
- Kashif
- How to Search for Files Recursively into Subdirectories
- 5 Answers 5
- bash
- Perl
- Python
- find
How can I recursively find all files in current and subfolders based on wildcard matching?
find needs a starting point, so the . (dot) points to the current directory.
I 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.
@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.
note 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.
Also 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
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 also has the -iname , -regex , and -iregex flags for case-insensitive wildcard, regex, and case-insensitive regex matching, so piping to grep is unnecessary.
However, piping to grep -v can allow you to use simple strings or regexes to remove entries you don’t want.
@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.
One important caveat here is that if you’re using find on a directory that contains A LOT of files (eg; «) then this can be quite slow.
find will find all files that match a pattern:
However, if you want a picture:
fd
In case find is too slow, try the fd utility — a simple and fast alternative to find written in Rust.
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
L 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.
In the wildcard-match you can provide the string you wish to match, e.g., *.c (for all C files).
Your answer is the first most correct here as it only searches files as specified. The others not specifying type will return directories.
By default, find detect symbolic file links (but not the ones in symbolic directory links). -type f will cause find to not detect symbolic file links. If you also want to include symlinks that point to a file, use -L : find -L -type f . Don’t use -type f,l since it will also include symbolic directory links.
If your shell supports a new globbing option (can be enabled by: shopt -s globstar ), you can use:
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:
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:
Alternatively you can use a fd utility with a simple syntax, e.g. fd pattern .
@Broncha Because you need to activate the extended globbing by shopt -s globstar command. This is supported in Bash, zsh and similar shells.
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.
find . -type f -name 'text_for_search'
If you want use a regular expression, use -iname :
find . -type f -iname 'text_for_search'
The default way to search for files recursively, and available in most cases is
It starts recursively traversing for filename or pattern from within the current directory where you are positioned. With the find command, you can use wildcards, and various switches. To see the full list of options, type
Or if man pages aren’t available at your system:
However, there are more modern and faster tools than find, which are traversing your whole filesystem and indexing your files. One such common tool is locate or slocate/mlocate. You should check the manual of your OS on how to install it, and once it’s installed, it needs to initiate the database. If the install script doesn’t do it for you, it can be done manually by typing
And, to use it to look for some particular file, type:
Or, to look for a filename or pattern from within the 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 the pattern that you have typed. To see the full list of locate’s options, type: locate —help or man locate
Additionally, you can configure locate to update its database on scheduled times via a cron job, so a sample cron which updates the database at 1 AM would look like:
These cron jobs need to be configured by root, since updatedb needs root privileges to traverse the whole filesystem.
How to Recursively Find all Files in Current and Subfolders Based on Wildcard Matching in Linux
Finding a specific file through a terminal in Linux is one of the common operations. Most of the files management systems use it. This tutorial covers finding single file, multiple files, folder, and subfolder recursively in Linux based on Wildcard.
What are Wild Cards
Wildcards are commonly used in computer programming and in various computer applications, such as text editors, search engines, and command-line interfaces.
They can be used to match or search for specific patterns or characters in a file or a string. Wildcards can also be used to create more flexible and powerful search queries, making it easier to find and manipulate the desired data.
Types of Wild Cards
Examples of common wildcard characters include the asterisk (*) and the question mark (?).
- Asterisk (*): The asterisk can be used to check for the files that match character sequences.
- Question mark (?): The question mark can be used to match any single character.
Recursively Find all Files in Current and Subfolders Based on Wildcard Matching
Finding all files in a directory and its subdirectories that match a specific pattern can be done using the “find” command in Linux. The “find” command can search files based on various criteria, such as name, permissions, type, and number of characters in file name.
To learn more about find command run the given command:
1: Finding Files Using Asterisk (*) Wildcard
To recursively find all files in the current directory and its subdirectories that match a wildcard pattern, you can use the following find command and below is the syntax for it:
The “” is a wildcard that matches any characters, so this command will find all files with names that end in “file-name”.
To find a specific directory:
To find all the directories with same name we will use a wildcard at the end of directory name:
To find all the directories and subdirectories, use wildcards at beginning and end of the directory name:
2: Finding Files Using Question mark (?) Wildcard
To find files with a specific number of characters then “?” wild card can be used, for example, if we want to find directories that contains 4 unknown characters then use:
Another way of finding recursively all files in current and subfolders based on wildcard matching in Linux pipe grep with find command:
Finding Files Using tree Command
The tree command is another useful command to find files and directories. To install tree utility use:
For more help about tree command, run:
Conclusion
This article covers a few examples of using the “find” command with Wildcards Question mark (?) and Asterisk (*). Using these two Wildcards we can create complex search patterns that can help you quickly locate specific files on your system. Lastly, we also cover the tree command that can find the files, folders and subfolders recursively in Linux. Using tree command a tree can be drawn for better illustration of all files inside a single directory.
About the author
Kashif
I am an Electrical Engineer. I love to write about electronics. I am passionate about writing and sharing new ideas related to emerging technologies in the field of electronics.
How to Search for Files Recursively into Subdirectories
I am trying to look for all XML files in a particular directory and all sub-directories (recursively) inside it. ls -R *.xml is only listing files in the current directory. I am quite sure, the sub-folders themselves have several .xml files, but none are showing up. Is this a configuration issue?
5 Answers 5
. is the current directory. If you need to search in another directory, replace . with the directory path.
Does it search for the required file recursively in the directory rooted at current directory. In my case it just checked in the current directory only, didn’t check the subdirectory.
Actually I searched for .php files in current directory. But it returned only .php files in current directory, didn’t searched recursively in sub-directories. That’s why I’m asking whether find command searches recursively or not.
@mostafiz, the find command searches recursively. If you don’t quote the parameter, I think your shell might do an expansion on the * , so it will match the files in the current directory.
sudo find . -print | grep -i '.*[.]xml'
-1 for mixing find and grep , when find can do filtering using both regexes and globs, and not using find ‘s -print0 and grep’s -z when you do need to mix.
ls doesn’t have options to filter the output. For that you would need to use pipe. This passes the output from ls to grep , which then filters them to show just the .xml files.
bash
Using globstar shell option, we can make use of recursive globbing ./**/*
bash-4.3$ shopt -s globstar bash-4.3$ for i in ./**/*.xml; do printf "%s\n" "$i" ; done ./adwaita-timed.xml ./bin/hw5/stuff/book/chapter42servletexample/build/web/META-INF/context.xml ./bin/hw5/stuff/book/chapter42servletexample/build/web/WEB-INF/beans.xml ./bin/hw5/stuff/book/chapter42servletexample/build/web/WEB-INF/web.xml
Perl
Perl has a module Find , which allows for recursive directory tree traversal. Within the special find() function, we can define a wanted subroutine and the directory that we want to traverse, in this example that’s . . The one-liner in such case would be:
bash-4.3$ perl -le 'use File::Find; find(sub,".")' ./adwaita-timed.xml ./CLEAR_DESKTOP/blahblah/hw5/stuff/book/jsf2demo/build/web/WEB-INF/beans.xml ./CLEAR_DESKTOP/blahblah/hw5/stuff/book/jsf2demo/build/web/WEB-INF/web.xml ./CLEAR_DESKTOP/blahblah/hw5/stuff/book/liangweb/build.xml
Python
While Perl has a whole module dedicated to recursive tree traversal, Python has a neat function walk() that is part of os module, and repeatedly returns tuple of topmost path, list of all subdirectories, and list of filenames. We can do the following:
bash-4.3$ python -c 'import os,sys; [ sys.stdout.write(os.path.join(r,i)+"\n") for r,s,f in os.walk(".") for i in f if i.endswith(".xml") ]' ./adwaita-timed.xml ./CLEAR_DESKTOP/blahblah/hw5/stuff/book/jsf2demo/build/web/WEB-INF/beans.xml ./CLEAR_DESKTOP/blahblah/hw5/stuff/book/jsf2demo/build/web/WEB-INF/web.xml ./CLEAR_DESKTOP/blahblah/hw5/stuff/book/liangweb/build.xml
This might be far neater as a script:
#!/usr/bin/env python import os,sys for r,s,f in os.walk("."): for i in f: if i.endswith(".xml") print(os.path.join(r,i))
find
Other answers have mentioned find for recursive traversal, and that’s the go-to tool for the job. What does need mention is the fact that find has multiple command line switches, such as -printf to print output in desired format, -type f to find only regular files, -inum to search by inode number, -mtime to search by modification date, -exec <> \; to execute a particular command to process the file with passing file as argument ( where <> is standard find placeholder for current file) , and many others so please read the manpage for find .