查找所有文件名包含特定字符串的文件

262

我一直在寻找一个命令,可以返回当前目录中文件名中包含某个字符串的文件。我看到了 locatefind 命令可以查找以某个词开头的文件 first_word* 或以某个词结尾的文件 *.jpg

我该如何返回包含某个字符串的文件列表呢?

例如,如果当前目录下有一个名为 2012-06-04-touch-multiple-files-in-linux.markdown 的文件。

我应该如何返回包含 touch 字符串的文件及其他文件?使用像 find '/touch/' 这样的命令。


这个问题在这里有更多的答案:如何基于通配符匹配递归查找当前和子文件夹中的所有文件? - EvgenKo423
8个回答

447

使用find命令:

find . -maxdepth 1 -name "*string*" -print

它会在当前目录中查找所有包含"string"的文件(如果你想递归查找,则删除maxdepth 1),并将其打印在屏幕上。

如果你想避免包含“:”的文件,则可以输入:

find . -maxdepth 1 -name "*string*" ! -name "*:*" -print

如果你想使用grep(但只要你不想检查文件内容,我认为这是不必要的),你可以使用:

ls | grep touch

但我重申,find是你任务的更好、更清洁的解决方案。


7
@Dru,如果您想让它更“简短”,可以避免使用“-print”,因为这是默认行为,并且避免使用“。”,因为这是它检查的默认文件夹。 - Zagorax
2
“find . -name "string"很好用。但我把。`去掉就会出错。再次感谢@Zagorax。” - Dru
只是一个观察,上述命令抱怨了“-maxdepth”参数的位置,最好像@Sunil Dias提到的那样将其移动到“-name”之前。 - Saikat
我有一个针对给定目录的命令 find *.jpg -name "*from*" -print。如何使其递归搜索?我已经尝试了 -maxdepth - zadrozny
你可能想要忽略大小写,使用以下命令:ls | grep -i touch - RaSor
显示剩余3条评论

24

使用如下命令来使用grep:

grep -R "touch" .

-R 表示递归。如果您不想进入子目录,则跳过它。

-i 表示“忽略大小写”。您可能也会觉得这值得一试。


1
尝试:grep -R "touch" . | cut -d ":" -f 2 - carlspring
1
那似乎只会产生文件的内容。不过您已经基本回答了我的问题,我可以尝试一些挖掘来保留内容。 - Dru
他们要求的是包含特定字符串的文件名,而不是文件的实际内容。 - Pranjal Sahu
@sahu,你可以通过追加 | cut -d ":" -f 1 进一步处理它,所以我不认为需要点踩。 - carlspring
无法处理二进制文件,就像我的情况一样。另外,请编辑您的答案,这将有助于未来的读者,而不是在评论部分挖掘。 - Pranjal Sahu
显示剩余4条评论

7
-maxdepth选项应该在-name选项之前,如下所示。
find . -maxdepth 1 -name "string" -print

3
在“字符串”前后加上星号“*”。 - aerin

4
find $HOME -name "hello.c" -print

这个命令将在整个$HOME(即/home/username/)系统中搜索所有名为“hello.c”的文件,并显示它们的路径:

/Users/user/Downloads/hello.c
/Users/user/hello.c

然而,它将不会匹配 HELLO.C 或者 HellO.C。如果要进行大小写不敏感的匹配,请使用 -iname 选项,如下所示:

find $HOME -iname "hello.c" -print

样例输出:

/Users/user/Downloads/hello.c
/Users/user/Downloads/Y/Hello.C
/Users/user/Downloads/Z/HELLO.c
/Users/user/hello.c

-type f选项传递以仅搜索文件:

find /dir/to/search -type f -iname "fooBar.conf.sample" -print
find $HOME -type f -iname "fooBar.conf.sample" -print

-iname 在GNU或BSD(包括OS X)版本的find命令上都可以使用。如果您的find命令版本不支持-iname,请尝试使用以下语法与grep命令:

find $HOME | grep -i "hello.c"
find $HOME -name "*" -print | grep -i "hello.c"

或者尝试

find $HOME -name '[hH][eE][lL][lL][oO].[cC]' -print

样例输出:
/Users/user/Downloads/Z/HELLO.C
/Users/user/Downloads/Z/HEllO.c
/Users/user/Downloads/hello.c
/Users/user/hello.c

0

除了已经提供的许多解决方案之外,另一个选择是利用 glob **。当您使用带有选项 globstarshopt -s globstar)的 bash 或者使用 zsh 时,您可以直接使用 glob **

**/bar

递归地搜索名为bar的文件夹(可能包括当前文件夹中的bar文件)。请注意,这不能与同一路径段内的其他通配符组合使用;在这种情况下,*运算符会恢复其通常的效果。

请注意,在这里zshbash之间存在微妙的差别。尽管bash将遍历到目录的软链接,但zsh不会。对于此,您必须在zsh中使用全局通配符***/


0
如果字符串在名称开头,你可以这样做。
$ compgen -f .bash
.bashrc
.bash_profile
.bash_prompt

4
“compgen”不是用于解决这个问题的合适方法。这个很少使用的工具被设计用来列出可用命令,因此它会列出当前目录中的文件(其中可能包括脚本),但它既不能递归查找,也不能查看文件名的开头或搜索文件内容,因此它基本上是无用的。 - msanford

-1
find / -exec grep -lR "{test-string}" {} \;

2
此答案因质量低被标记,请解释您建议的更改会做什么。 - Miroslav Glamuzina

-3
grep -R "somestring" | cut -d ":" -f 1

3
这似乎是对不同问题的回答 - 但由于您没有提供解释,这对提问者或其他人来说并不明显。 - Toby Speight

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接