command to find files by searching only part of their names?
Solution 1
Finding Files with bat
Anywhere
To find all files anywhere inside /path/to/folder
whose names contain bat
, you can use:
find /path/to/folder -name '*bat*'
I have quoted the search pattern *bat*
because, if the quotes were omitted and files match *bat*
in the current directory, the shell will expand *bat*
into a list of them and pass that to find
. Then find
wouldn't work right. (\*bat\*
and "*bat*"
also work.)
To search in the folder you're currently in (e.g., that you've cd
ed to), use .
, as usual:
find . -name '*bat*'
To search your whole computer, use /
. To search your home directory, use ~
, or the full name of your home directory. (The shell expands ~
to your home directory's fully qualified path.)
Broadening or Narrowing Your Search, Based on Name
If you want to search case-insensitively, so files containing BAT
, bAt
, and so forth are matched, use the -iname
test instead of the -name
test:
find /path/to/folder -iname '*bat*'
I've noticed all your files end in .c
. If you only want to find files like that, use:
find /path/to/folder -name '*bat*.c'
I noticed all your filenames have bat
either at the very beginning or the very end of the part preceding the .c
suffix. If you want to avoid matching files like embattled.c
, you could use:
find /path/to/folder -name '*bat.c' -o -name 'bat*.c'
-o
is the or operator.
Matching Only Files
To find only regular files--and not folders, symbolic links, and special device nodes--you can use -type f
. This is frequently recommended and sometimes quite appropriate... but often not what you really want, especially if you're running find
for the purpose of examining the output yourself. If you had a symbolic link that matched your search, wouldn't you want to know about it?
If you want to find both regular files and symbolic links, you can use:
find /path/to/folder -name '*bat*' \( -type f -o -type l \)
That uses the -o
operator and also parentheses for grouping (which must be quoted so the shell does not treat them specially; otherwise you'll get a syntax error).
But suppose you only want to see symbolic links that ultimately point to a regular file (and not symbolic links to directories, device nodes, etc.). That's actually even simpler: use -xtype
instead of -type
. Provided you're not running find
with -L
flag, -xtype
on a symbolic link tests the type of the file the link points to.
find /path/to/folder -name '*bat*' -xtype f
If you have a symlink to another symlink to a file, -xtype f
will match it even though its direct target is another symlink rather than a regular file. This is almost always what you want.
Often people think they want -type f
, but really they want -xtype f
.
Getting Detailed Output
find
's default action if you don't specify one is -print
. All the commands given above are equivalent to themselves with -print
tacked on at the end.
find
is often used to run commands based on the files found--often, commands that make changes. But there are also other actions whose purpose is to display results, besides -print
. Of particular interest is -ls
:
find /path/to/folder -name '*bat*' -ls
This gives detailed information on each file, in a multi-column format, similar to (though not quite the same as) what you would see by running ls file
.
Further Reading
For more information on find
and other ways to find files, see:
-
The
find
manual page, accessible online or by runningman find
in a terminal. - The GNU findutils reference manual, providing extensive documentation on the
find
,locate
, andxargs
utilities. - FindingFiles in the Ubuntu help wiki, which shows how to use find as well as several other methods.
Solution 2
The easiest way is to run
locate bat
This way you can search through the whole computer for files containing "bat" in the file name
To refresh the list of files on your PC run
updatedb
Run this command when you have recently added new files to your account
Solution 3
Open the terminal and change directories to the directory from where you want to start searching and then run this command:
find . -name "*bat*" -type f
The .
starts the find command from the current directory.
The -name
matches the string bat
and is case sensitive. (-iname
is case insensitive)
The -type f
searches for files only.
Solution 4
If the files are in the current directory use:
$ ls *bat*
batgirl.c batman.c batwoman.c cricketbat.c
Or (to have them line by line):
$ ls -1 *bat*
batgirl.c
batman.c
batwoman.c
cricketbat.c
If you want to search the system for that files, use:
$ find / -name "*bat*"
/path/to/cricketbat.c
/path/to/batgirl.c
/path/to/batwoman.c
/path/to/batman.c
Solution 5
You want to use the find
command, with the -iname
option for case insensitive file name matching, or the -name
option for case sensitive file name matches. Both of these will let you use wildcard names. So, to find any file names which contain "bat" you would use:
find / -iname '*bat*'
Or
find / -name '*bat*'
The *
means "any character(s)", so the search is looking for bat
with any characters, including none, before or after it. The /
searches from the root directory recursively, you can use .
which will search recursively from the current directory, or the absolute path for where you want to search from.
Take a look at how search for files using regex in linux shell script
Related videos on Youtube
srk_cb
"Losing can persuade you to change what doesn't need to be changed, and winning can convince you everything is fine even if you are on the brink of disaster" -Garry Kasparov
Updated on September 18, 2022Comments
-
srk_cb over 1 year
Say there are files with names:
batman.c debate.c cricketbat.c
What command and how should I use it to list all these files by using the searchtag
bat
?-
steeldriver about 9 yearsDo you want to list matching files in only the current directory? in any directory at or below the current directory? anywhere on the system?
-
-
Sergiy Kolodyazhnyy about 9 yearsneeds
updatetdb
-
Eliah Kagan about 9 years@Serg To find new files (newer than the last time
updatedb
was last manually or automatically run),sudo updatedb
would need to be run first, yes. -
A.B. about 9 yearsdelete and undelete? ok +1 :P ;)
-
terdon about 9 yearsNote that this will search the entire system for names matching
bat
. -
Mark Kirby about 9 years@terdon I already stated this in the answer, don't think it deserved the down vote when I already stated this.
-
terdon about 9 yearsI was just making it clear to the OP. What downvote?
-
Mark Kirby about 9 years@terdon, sorry I assumed from your comment it was you who down voted from 2 to 1 must of been just a coincidence and it went back up a minuet ago, so don't know whats going on there.
-
AJefferiss about 9 years@EliahKagan thanks, I've added some more information to my answer.
-
Eliah Kagan about 9 years+1 Thanks for the edit. IMO it is a strength of this answer that it avoids recommending the indiscriminate use of
-type f
, which does more than simply excluding directories and is often not what users really want. -
Timothy Gu about 9 yearsNote that this is A LOT faster than
find /
aslocate
searches from a database, whilefind
recursively lists/
and then matches the regex. -
mklement0 about 9 yearsGreat answer, especially the
-xtype
advice; perhapsls *bat*
and-maxdepth
/mindepth
are also worth mentioning. -
Eliah Kagan about 9 years@mklement0 Thanks! The OP hasn't yet provided clarification about where the files are and whether or not recursion is needed. As chaos's answer covered
ls
already, I focused on the recursive case withfind
here. Of course, a detailed answer covering non (or less)-recursive listing of filenames matching some pattern (ls
andfind
with-maxdepth
) would also be useful. You might want to post such an answer!