I have been searching for a command that will return files from the current directory which contain a string in the filename. I have seen locate
and find
commands that can find files beginning with something first_word*
or ending with something *.jpg
.
How can I return a list of files which contain a string in the filename?
For example, if 2012-06-04-touch-multiple-files-in-linux.markdown
was a file in the current directory.
How could I return this file and others containing the string touch
? Using a command such as find '/touch/'
Use find
:
find . -maxdepth 1 -name "*string*" -print
It will find all files in the current directory (delete maxdepth 1
if you want it recursive) containing "string" and will print it on the screen.
If you want to avoid file containing ':', you can type:
find . -maxdepth 1 -name "*string*" ! -name "*:*" -print
If you want to use grep
(but I think it's not necessary as far as you don't want to check file content) you can use:
ls | grep touch
But, I repeat, find
is a better and cleaner solution for your task.
Use grep as follows:
grep -R "touch" .
-R
means recurse. If you would rather not go into the subdirectories, then skip it.
-i
means "ignore case". You might find this worth a try as well.
The -maxdepth
option should be before the -name
option, like below.,
find . -maxdepth 1 -name "string" -print
find $HOME -name "hello.c" -print
This will search the whole $HOME
(i.e. /home/username/
) system for any files named “hello.c” and display their pathnames:
/Users/user/Downloads/hello.c
/Users/user/hello.c
However, it will not match HELLO.C
or HellO.C
. To match is case insensitive pass the -iname
option as follows:
find $HOME -iname "hello.c" -print
Sample outputs:
/Users/user/Downloads/hello.c
/Users/user/Downloads/Y/Hello.C
/Users/user/Downloads/Z/HELLO.c
/Users/user/hello.c
Pass the -type f
option to only search for files:
find /dir/to/search -type f -iname "fooBar.conf.sample" -print
find $HOME -type f -iname "fooBar.conf.sample" -print
The -iname
works either on GNU or BSD (including OS X) version find command. If your version of find command does not supports -iname
, try the following syntax using grep
command:
find $HOME | grep -i "hello.c"
find $HOME -name "*" -print | grep -i "hello.c"
OR try
find $HOME -name '[hH][eE][lL][lL][oO].[cC]' -print
Sample outputs:
/Users/user/Downloads/Z/HELLO.C
/Users/user/Downloads/Z/HEllO.c
/Users/user/Downloads/hello.c
/Users/user/hello.c
If the string is at the beginning of the name, you can do this
$ compgen -f .bash
.bashrc
.bash_profile
.bash_prompt
grep -R "somestring" | cut -d ":" -f 1
An alternative to the many solutions already provided is making use of the glob **
. When you use bash
with the option globstar
(shopt -s globstar
) or you make use of zsh
, you can just use the glob **
for this.
**/bar
does a recursive directory search for files named bar
(potentially including the file bar
in the current directory). Remark that this cannot be combined with other forms of globbing within the same path segment; in that case, the *
operators revert to their usual effect.
Note that there is a subtle difference between zsh
and bash
here. While bash
will traverse soft-links to directories, zsh
will not. For this you have to use the glob ***/
in zsh
.