关于 find 命令的15个超级有用的例子

系统 Linux
本文我们会分享关于 find 命令的一些常见示例。不过在此之前,我们先来看一下它的语法,以及如何使用。

find 命令用于在 Linux 命令行中搜索文件和目录。

find 是功能最强大、使用最频繁的命令之一,同时也是选项最多的命令之一,它有50多个选项,很容易让人弄混了,特别是当它与 exec 或 xargs 命令一起使用的时候。

作为系统管理员或者软件开发者,在命令行中工作时都不可避免的会使用到 find 命令。所以,与其畏难而逃避它,不如知难而进,拥抱它的力量。

本文我们会分享关于 find 命令的一些常见示例。不过在此之前,我们先来看一下它的语法,以及如何使用。

Linux 中的 find 命令

find 命令的一般语法为:

find [directory to search] [options] [expression]

方括号 [] 中所有的内容都是可选的,这意味着你可以在没有任何选项和参数的情况下运行 find 命令。不过这只会打印出当前路径下所有的文件和目录,这样没什么用处,对吧?

我们来详细了解一下它的参数。

  • directory to search:要搜索的目录,基本上就是我们要开始搜索的位置。默认情况下,搜索是递归的(也会搜索子目录),从当前位置开始;
  • options:选项,指定搜索的类型,可以按文件名称、文件类型、修改时间等(进行搜索),这里有50多个选项;
  • expression:指定的搜索词。如果是要按文件名查找,那么搜索词就是文件名;如果是要查找名称与表达式匹配的文件,那这里就用表达式。

看下面的例子:

find . -type f -name myfile

该命令将在当前目录及其子目录中进行搜索,查找名为 myfile 的文件(不是目录)。选项 -type f 表示只查找文件,单点 . 表示当前目录。

按名称查找文件和目录

可以按文件名搜索文件和目录:

find . -name SEARCH_NAME

由于没有指定文件类型,所以它会搜索具有给定名称的文件和目录。

下面的例子找到名为 mystuff 的文件和目录:

[gliu@fedora work]$ find -name mystuff./new/mystuff./mystuff

只查找文件或目录

如果只想查找文件,那么需要指定文件类型 -f

find . -type f -name SEARCH_NAME

类型和名称的顺序无关紧要。上一个例子中,只查找文件,可使用如下命令:

[gliu@fedora work]$ find -type f -name mystuff./mystuff

如果只搜索目录,那么指定类型 -d

find . -type d -name SEARCH_NAME

还是上面那个例子,如果只查找目录,使用如下命令:

[gliu@fedora work]$ find -type d -name mystuff./new/mystuff

执行不区分大小写的搜索

默认情况下,find 命令区分大小写。如果我们想要执行不区分大小写的搜索,可以使用 -iname 来代替 -name

find . -type f -iname SEARCH_NAME

也可以将其与 -d 选项一起使用。

[gliu@fedora work]$ find -iname mystuff./new/mystuff./MyStuff./mystuff

按扩展名搜索(重要)

find 命令最常见的用法之一就是查找指定类型的文件,或者说是按照文件扩展名来进行查找。

比如,我们要在当前目录下搜索所有的 C++ 文件,而C++文件的扩展名是 .cpp,所以我们可以这样搜索:

find . -type f -name "*.cpp"

这样,我们告诉 find 命令查找类型为文件(file),并且以 .cpp 结尾的文件。

[gliu@fedora work]$ find . -type f -name "*.cpp"
./file.cpp
./.cargo/registry/src/github.com-1ecc6299db9ec823/libz-sys-1.1.3/src/zlib/contrib/iostream2/zstream_test.cpp
./.cargo/registry/src/github.com-1ecc6299db9ec823/libz-sys-1.1.3/src/zlib/contrib/iostream/test.cpp
./.cargo/registry/src/github.com-1ecc6299db9ec823/libz-sys-1.1.3/src/zlib/contrib/iostream/zf

注意:在使用 find 命令时,需要将表达式放在双引号中。

为什么要将表达式放在双引号中呢?因为如果要不这样做的话,shell会扩展通配符,将其替换为当前目录中所有以 .cpp 结尾的文件。

比如,假如当前目录下有两个文件:file1.cpp, file2.cpp,那么下面的命令:

find . -type f -name *.cpp

会被shell扩展为:

find . -type f -name file1.cpp file2.cpp

这种情况下,shell 就会给出提示:

find: paths must precede expression: 'file1.cpp'find: possible unquoted pattern after predicate '-name'?

另外,如果当前目录下只有一个扩展名为.cpp的文件,那就可以。

搜索多个扩展名(或条件)的多个文件

上述命令搜索给定扩展名的文件。那如果要同时搜索不同扩展名的文件,该怎么办呢?

可以使用逻辑或(OR) -o 来运行 find 命令:

find . -type f -name "*.cpp" -o -name "*.txt"

这样,就会搜索扩展名为 .cpp 或 .txt 的文件:

[gliu@fedora work]$ find . -type f -name "*.txt" -o -name "*.cpp"
./new.txt
./file.cpp
./new/new.txt
./new/dir2/another.txt
./new/dir1/new.txt
./another.txt

在指定目录中查找文件

我们上面的例子都是在当前目录中搜索,因为我们在命令中指定了 . 作为当前路径。

点 . 可以替换为绝对路径或者相对路径。这样我们就可以在不离开当前路径的情况下,在指定的目录中查找文件。

[gliu@fedora work]$ find ./new -name mystuff ./new/mystuff

在多个目录中搜索文件

如果你认为所要查找的文件可能位于多个位置,那么不必多次运行 find 命令,只需在 find 命令中指定要搜索的所有目录路径即可:

find ./location1 /second/location -type f -name "pattern"

查找空文件和目录

-empty 选项可以让你使用 find 命令查找空文件和目录。比如要查找当前路径下所有的空文件和目录,可使用如下命令:

find . -empty

也可以指定搜索的文件类型,只查找文件或者目录:

find . -empty -type f

还可以结合文件名使用:

find . -empty -type f -name "*.cpp"

查找大文件或小文件(根据文件大小搜索)

根据文件的大小执行搜索,可以查找大文件或者小文件。但这只适用于文件,不适用于目录。

要根据文件的大小搜索,可以使用 -size 选项,后面跟上一个值N(即文件的大小),+N 查找大于 N 的文件,-N 查找小于 N 的文件

比如,查找大小正好为 50KB 的文件:

find . -size 50k

在当前路径下查找大于 1G 的文件:

find . -size +1G

查找小于 20 bytes 的文件(注意单位是c而不是b):

find . -size -20c

要查找大于100 MB 但小于 2 GB 的文件:

find . -size +100M -size -2G

此外,还可以结合名称搜索。比如,要在根目录中查找以 .log 结尾,大于500MB的文件,可使用如下命令:

find / -size +500M -name "*.log"

关于文件大小值 N 的单位:

  • c : bytes(字节)
  • k: kilobytes(千字节)
  • M: Megabytes(兆字节)
  • G: Gigabytes(GB)

查找最近修改的文件(根据修改或创建时间搜索)

我们先来简单介绍下mtime, atime ctime 的概念:

  • mtime:文件上次修改的时间;
  • ctime:文件创建的时间;
  • atime:文件上次访问的时间。

我们经常会有查找最近修改过的文件的需求,这时候,可以按修改时间来搜索文件。

比如,要查找 3天(3 * 24H)以内修改过的所有文件:

find . -type f -mtime -3

再比如,查找 5天以前创建的文件:

find . -type f -ctime +5

上述命令是以天为单位。那么,如果要搜索几分钟前修改过的文件呢?可以使用 mmin, amin cmin

比如,要查找 5分钟以内修改过的文件,可使用如下命令:

find . -type f -mmin -5

此外,还可以结合名称,指定时间的上限和下限进行搜索。比如,下面的命令将搜索过去20分钟到30分钟内,修改过的所有 .java 文件:

find . -type f -mmin +20 -mmin -30 -name "*.java"

查找具有特定文件权限的文件

find命令允许您搜索具有特定权限的文件。

find -perm mode

比如,在当前路径下查找所有权限模式为 777 的文件:

find . -perm 777

查找具有读写权限的文件(完全匹配,如果文件权限为 读写和执行,则不匹配):

find . -perm a=r+w

根据文件的所属用户查找

find 还可以根据文件的所有权进行搜索。

比如,在当前路径下搜索用户 John 所拥有的文件:

find . -type f -user John

当然,也可以与其他选项(比如文件大小,时间,名称等)结合使用:

find . -type f -user John -name "*.cpp"

不递归查找,仅在当前目录中搜索

默认情况下,find 命令在当前位置的所有子目录中搜索。如果不希望这样,可以将搜索深度指定为 1。这将限制搜索仅限于当前目录,不包括任何子目录。

find . -maxdepth 1 -type f -name "*.txt"

图片



从搜索中排除目录

如果要将某个目录从搜索中排除,可以结合 -path, -prune-o 一起使用:

find . -path "./directory_exclude/*" -prune -o -name SEARCH_NAME

注意路径中的星号 *, -prune 选项在路径之后,-o 选项在 prune 之后。

基本上,prune命令要求不使用路径指定的值,它总是与 -o 一起使用,以确保 -o 的右侧只针对未被排除的目录。

处理 find 命令的输出结果(使用 exec 和 xargs)

到目前为止,我们介绍了关于find命令的一些标准查找文件的方法。此外,还可以通过对 find 命令的结果执行某些操作,来改进它。

例如,查找与特定名称模式匹配的文件并一次性重命名,或者查找空文件并删除。

我们知道,管道重定向可以用于将一个命令的输出与另一个命令输入相结合。但这对find命令的输出不起作用,至少不直接起作用。

如果要对find命令的结果执行操作,有两个选项,即 exec xargs

使用 find 和 exec

假如我们要对 find 的结果使用 ls -l 列出来,看下面的例子:

find . -type f -name "*.txt" -exec ls -l {} +

以下是输出:​

[gliu@fedora work]$ find . -type f -name "*.txt" -exec ls -l {} +
-rw-rw-r-- 1 gliu gliu 39 Oct 13 19:30 ./another.txt
-rw-rw-r-- 1 gliu gliu 35 Oct 13 15:36 ./new/dir1/new.txt
-rw-rw-r-- 1 gliu gliu 35 Oct 13 15:36 ./new/dir2/another.txt
-rw-rw-r-- 1 gliu gliu 35 Oct 13 18:51 ./new/mystuff/new.txt
-rwxrwxrwx 1 gliu gliu 35 Oct 13 15:37 ./new/new.txt
-rw-rw-r-- 1 gliu gliu 35 Oct 13 18:16 ./new.txt

不要忘记 exec 命令最后的 {} +,并且要注意 {} + 之间的空格。

花括号 {} 引用 find 命令的结果,你可以将其认为是 {file1, file2, file3}。加号 + 用于终止 exec 命令。

exec 还有另一个约定:

find . -type f -name *.txt" -exec ls -l

上述命令中,分号 ; 用于代替加号 +,分号前面的反斜杠 \ 用于转义特殊字符。

{} + 的优点是它运行的命令更少,它就相当于是 ls -l file1 file2 file3;而 {} \ 则相当于运行 ls -l file1, ls -l file2, ls -l file3

但是,{} \;具有在同一 exec 语句中多次使用 {} 的优点。例如,下面的命令将使用 .old 扩展名重命名所有找到的文件:

find . -type f -name *.txt" -exec mv {} {}.old

使用 xargs

许多 Linux 用户已经习惯了管道重定向。这个带有尾随 { }+ 的 exec 命令对他们来说似乎不太习惯。

这就是 xargs 命令存在的价值,你只需要通过管道将 find 命令的输出解析到 xargs 命令:

find . -type f -name *.txt" | xargs ls -l

图片


find 结合 grep 使用

上面我们介绍了 find 结合 exec xargs 命令的使用,此外,还可以将 find 与 grep 命令一块使用。

对于任何系统管理员或软件开发人员来说,find 和 grep 是最常见且最有用的组合之一。

你可以使用 find 命令来查找文件,然后使用 grep 命令来搜索这些文件的内容。

比如,我们要搜索所有包含 “Alice”一词的 txt 文件,那么可以这样搜索:

find . -type f -name "*.txt" -exec

同样的,也可以使用 xargs 命令:

find . -type f -name "*.txt"

图片


当然,这是最简单的例子,如果你熟悉 grep 命令,可以根据自己的需求和喜好使用它。

find 命令的用法还有很多,我们列举了一些相对比较常用的。当你开始熟悉 find 命令的时候,就可以在各种情况下使用。

责任编辑:庞桂玉 来源: TIAP
相关推荐

2013-10-08 15:51:03

Linux find命

2013-10-08 16:24:34

Linux find命

2020-05-20 13:45:52

Linuxtouch命令

2022-12-22 14:44:06

JavaScript技巧

2022-12-25 16:03:31

JavaScript技巧

2023-07-18 07:56:31

工具reduce业务

2023-06-28 00:02:40

2020-04-16 14:20:16

Linuxtouch命令

2018-08-03 11:07:52

dd命令备份Linux系统

2023-01-09 10:29:41

mv命令Linux

2022-12-19 15:23:51

JavaScrip开发语言

2023-05-30 15:11:16

JavaScrip开发功能

2023-03-24 10:07:46

tail命令

2023-03-23 21:08:59

head命令

2015-09-28 11:22:55

命令行补全Linux

2012-01-17 13:54:02

PHP

2011-04-15 15:16:18

代码编程

2020-06-17 05:44:44

人工智能AI机器学习

2023-02-22 16:43:05

Web开发github

2020-12-14 11:43:27

人工智能智能软件
点赞
收藏

51CTO技术栈公众号