ChatGPT解决这个技术问题 Extra ChatGPT

How can I recursively find all files in current and subfolders based on wildcard matching?

How can I recursively find all files in current and subfolders based on wildcard matching?


M
Mateen Ulhaq

Use find:

find . -name "foo*"

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.
Worth stressing that " " is very necessary for recursive searching.
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
A
Andy Lester

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

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.
I don't think it is about being unnecessary, but being more convenient.
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.
t
the Tin Man

find will find all files that match a pattern:

find . -name "*foo"

However, if you want a picture:

tree -P "*foo"

Hope this helps!


brew install tree for Mac OSX users w/o apt-get installed
Tested on macOS Sierra, just add '--print' -> ' find . name "*foo" --print ' . superuser.com/questions/177289/searching-mac-through-terminal
sudo yum install tree -y for CentOS
k
kenorb

fd

In case, find is too slow, try fd utility - a simple and fast alternative to find written in Rust.

Syntax:

fd PATTERN

Demo:

https://github.com/sharkdp/fd/raw/master/doc/screencast.svg?sanitize=true

Homepage: https://github.com/sharkdp/fd


First time I've seen a gif on SO in almost 9 years. Nice job!
Those performance results look very promising. You might consider adding fd to home-brew...
off topic: what tool did you use to create svg file for demo?
@aprodan The demo image was copied from GitHub, but I believe they're using asciinema, then converted to GIF format, but I'm not sure.
Actually it's SVG format, so probably asciicast2vector can be used.
t
toddcscar
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


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.
That was the answer for me. Thanks!
k
kenorb

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.


This just goes into a single level. Not recursing into the sub directories for me
@Broncha Because you need to activate the extended globbing by shopt -s globstar command. This is supported in Bash, zsh and similar shells.
bash-3.2$ shopt -s globstar gives bash: shopt: globstar: invalid shell option name
@drewish You need to upgrade your Bash to 4.x
S
Shital Shah

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.


X
XYZ_Linux
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)


Your answer is the first most correct here as it only searches files as specified. The others not specifying type will return directories.
if you wish to search for a directory "-type f" could be changed to "-type d "
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 <optional_directory_path> -type f. Don't use -type f,l since it will also include symbolic directory links.
B
Benjamin W.

You can use:

# find . -type f  -name 'text_for_search'

If you want use REGX use -iname

# find . -type f  -iname 'text_for_search'

A
Alberto

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"

m
melchi

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.


locate "$PWD*.mp4" Just to remind that you may be able to skip the grep
A
Aleksandar Pavić

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.


A
Anshul Singhal

Following command will list down all the files having exact name "pattern" (for example) in current and its sub folders.

find ./ -name "pattern"


Downvote. This repeats a 2017 answer.
@Brian New answers are expected to provide some new info or an alternative solution, repeating what already has been said is not useful. Just like when asking a question, before writing an answer you should search first to make sure your answer will add something useful. Especially when there are lots of other answers, as in such case the possibility of this approaches 0. It's not hard at all, only a single Ctrl+F away.
Yes your are right. I agree now that i thought more about it.
S
Saman Bayat

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.


Downvote. These should have been comments under or edits of the 2011 accepted answer.
M
MukeshKoshyM

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"

why on earth do you use grep for that? Just redirect stderr to null find / -iname '*C*.xml' 2>/dev/null
J
Jay Yang

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

R
Robert Ranjan

Try with fd command if installed. Install instruction

find all file starts with 'name'

fd "name*"

This command ignores all .hidden and .gitignoreed files.

To include .gitignoreed files, add -I option as below

fd -I "name*"

To include hidden files, add -H option as below

fd -H "name*"

E
E_net4 - Mr Downvoter

With Python>3.5, using glob, . pointing to your current folder and looking for .txt files:

 python -c "import glob;[print(x) for x in glob.glob('./**/*txt', recursive=True)]"

For older versions of Python, you can install glob2


Can someone explain the downvotes? If there is something wrong with my answer, I would like to know what it is. – This question asks a native solution for Linux shells and you provide an answer in Python. So your answer is off-topic here.
I don't understand part of your comment @EvgenKo423, since this answer was answered by Katu and not by you.
@ValerioBozz Look at the revision history. I had quoted their question and answered it.
I have seen plenty of questions about sed with accepted answers that use awk and similar. [...] It feels like this is getting downvoted by people following the trend instead of thinking about it. – But both sed and awk are command line tools, while the Python is a full-featured programming language. Downvoting answers costs rep which discourages doing so for no reason, but if you still think it's a voting fraud, have a read of this post. P.S.: Please use comments or Stack Overflow Chat for discussions, they don't belong in answers.