find 命令用于在 Linux 命令行中搜索文件和目录。
find 是最强大和最常用的命令之一,它也是最广泛的命令之一,有 50 多个选项,这使它有点混乱,特别是当它与 exec 或 xargs 命令配对时。
系统管理员或软件开发人员在命令行中工作时不可能避免使用 find 命令。
我将讨论您可能会使用的一些最常见的 find 命令示例。
在 Linux 中查找命令
find 命令的一般语法是:
find [directory to search] [options] [expression]
括号 [] 中的所有内容都是可选的,这意味着您可以在find没有任何选项和参数的情况下运行命令,它只会转储当前位置的所有文件和目录。这不是很有用,对吧?
让我们更详细地看一下:
- directory to search基本上是您要开始搜索的位置,默认情况下,搜索是递归的,并从您当前的位置开始。
- options 指定搜索类型,可以是名称、类型、修改时间等,这里有 50 多个可能的选项。
- expression允许您指定搜索词。如果要按文件名查找文件,则表达式是文件名,如果要查找名称与模式匹配的文件,请在模式中表达。
我举个简单的例子:
find . -type f -name myfile
此命令将在当前目录及其子目录中运行搜索以查找名为myfile. 该选项-type f要求它仅查找文件,单点.表示当前目录。
让我们看看 find 命令的一些实际示例。
按名称查找文件和目录
您可以按名称搜索文件和目录:
find . -name SEARCH_NAME
由于没有提到文件类型,它会搜索具有给定名称的文件和目录。
下面的示例查找名为 mystuff 的文件和目录:
abhishek@LHB:~/Examples$ find -name mystuff
./new/mystuff
./mystuff
仅查找文件或仅查找目录
如果只想查找文件,请指定文件类型 -f:
find . -type f -name SEARCH_NAME
类型和名称的顺序无关紧要。以前面的例子为例,只查找文件:
abhishek@LHB:~/Examples$ find -type f -name mystuff
./mystuff
如果只想搜索目录,请指定类型 -d:
find . -type d -name SEARCH_NAME
在上一个文件中,仅查找目录:
abhishek@LHB:~/Examples$ find -type d -name mystuff
./new/mystuff
运行不区分大小写的搜索
默认情况下,find 命令区分大小写。您可以使用-iname代替使用给定名称运行不区分大小写的搜索-name。
find . -type f -iname SEARCH_NAME
你也可以使用它type d。
abhishek@LHB:~/Examples$ find -iname mystuff
./new/mystuff
./MyStuff
./mystuff
以上三个例子截图:
按扩展名搜索文件(重要)
find 命令最常见的用途之一是查找特定类型的文件,或者我应该说是特定的扩展名。
例如,假设您要搜索当前目录中的所有 C++ 文件。C++ 文件以扩展名 .cpp 结尾,因此您可以这样搜索:
find . -type f -name "*.cpp"
通过这种方式,您可以告诉 find 命令查找type file以.cpp.
abhishek@LHB:~$ 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/zfstream.cpp
“
使用 find 命令时,始终将搜索表达式放在双引号中。
”
为什么我建议在搜索词周围使用双引号或单引号?因为如果不这样做,shell 将扩展通配符。
如果您不将搜索词括在引号中:
find . -type f -name *.cpp
您的 shell 将展开 *.cpp 并将其替换为当前目录中名称以 .cpp 结尾的所有文件。
如果只有一个文件,这可能会起作用,但如果有多个文件,您的 shell 会抱怨语法不正确。
在上面的例子中,只有一个 cpp 文件,因此当命令扩展为 时find . -type f -name file.cpp,它file.cpp仍然有效,因为它仍然可以作为搜索词。
但是在同一目录中有两个 .txt 文件,因此当命令扩展到 时find . -type f -name another.txt new.txt,它会抱怨,因为现在有多个搜索词。
这就是为什么您应该始终将搜索词括在双引号中的原因。
搜索具有多个扩展名(或条件)的多个文件
上面的命令搜索具有给定扩展名的文件。如果您想查找具有不同扩展名的文件怎么办?
使用-o作为逻辑 OR 条件的选项运行一次,而不是多次运行 find 命令:
find . -type f -name "*.cpp" -o -name "*.txt"
下面是一个例子:
abhishek@LHB:~/Examples$ 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
在特定目录中查找文件
到目前为止,所有示例都在当前目录中执行搜索,因为您指定了 . 在示例中。
点可以替换为目录的绝对或相对路径,以便您可以在指定目录中查找文件而无需离开当前位置。
abhishek@LHB:~/Examples$ 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 参数执行的搜索找到大文件或小文件,这仅适用于文件,不适用于目录。
您可以使用-size带有 +N的选项来表示大于 N 的大小,使用带有 -N的选项来表示小于 N 的大小。
查找大小正好为 50 KB 的文件:
find . -size 50k
要在当前目录中搜索大于 1 GB 的文件:
find . -size +1G
要查找小于 20 字节的内容:
find . -size -20c
要查找大于 100 MB 但小于 2 GB 的文件:
find . -size +100M -size -2G
您也可以将尺寸搜索与名称搜索结合起来,例如,要在根目录中搜索名称以 .log 结尾但大小大于 500 MB 的所有文件,您可以使用:
find / -size +500M -name "*.log"
- c : 字节
- k: 千字节
- M: 兆字节
- G: 千兆字节
查找最近修改的文件(根据修改或创建时间搜索)
- mtime:文件最后修改时间
- ctime:文件的创建时间
- atime:文件的最后访问时间
您经常会发现自己想要查找所有最近修改过的文件。在这种情况下,按修改时间搜索会有所帮助。
要查找 3 天内(3*24H)修改的所有文件,请使用:
find . -type f -mtime -3
要查找至少 5 天(5*24H)前创建的所有文件,请使用:
find . -type f -ctime +5
我知道 24 小时是一个巨大的时间框架,如果您想搜索几分钟前修改过的文件怎么办?
为此,您可以使用mmin,amin和cmin。
要查找过去 5 分钟内修改过的所有文件,请使用:
find . -type f -mmin -5
您可以指定上限和下限以及搜索名称。下面的命令将搜索过去 20 到 30 分钟内修改过的所有 .java 文件。
find . -type f -mmin +20 -mmin -30 -name "*.java"
查找具有特定文件权限的文件
我希望您熟悉Linux 中的文件权限概念。
find 命令允许您搜索具有特定文件权限和访问模式的文件。
find -perm mode
例如,查找当前目录下所有访问方式为777的文件;
find . -perm 777
要查找所有具有读写访问权限的文件(完全匹配,如果文件对所有人具有执行权限,则不匹配):
find . -perm a=r+w
查找用户拥有的文件
您还可以根据所有权搜索文件。
例如,要在当前目录中查找用户 John 拥有的文件,请使用:
find . -type f -user John
您还可以将其与其他选项(如大小、时间和名称)结合使用:
find . -type f -user John -name "*.cpp"
不递归查找,只在当前目录中查找
默认情况下, find 命令在您当前位置的所有子目录中搜索,如果您不想这样做,您可以将搜索深度指定为 1。这会将搜索限制为仅当前目录并排除任何子目录。
find . -maxdepth 1 -type f -name "*.txt"
从搜索中排除目录
如果你想从搜索中排除一个目录,你可以通过组合路径、修剪和逻辑或来做到这一点。
find . -path "./directory_exclude/*" -prune -o -name SEARCH_NAME
小心目录路径中的 *,路径-prune后和-o修剪后。
基本上,prune 命令要求不使用路径指定的值。修剪始终用于-o确保仅对未修剪的目录评估术语的右侧。
对查找命令(exec 和 xargs)的结果采取行动
到目前为止,您已经了解了根据各种条件查找文件的各种方法。那挺好的,但是您可以通过对 find 命令的结果采取某些操作来使其更好。
例如,查找匹配特定名称模式的文件并一次重命名它们或查找空文件并删除它们如何?
您知道管道重定向可用于将一个命令的输出与另一个命令的输入组合起来。但这不适用于 find 命令的输出,至少不能直接使用。
如果您想对 find 命令的结果采取行动,您有两个选择:
- 使用 exec
- 使用 xargs
使用查找和执行
假设您想使用 find 命令长列表 (ls -l) 搜索文件。这是你使用的:
find . -type f -name "*.txt" -exec ls -l {} +
这是输出:
abhishek@LHB:~/Examples$ find . -type f -name "*.txt" -exec ls -l {} +
-rw-rw-r-- 1 abhishek abhishek 39 Oct 13 19:30 ./another.txt
-rw-rw-r-- 1 abhishek abhishek 35 Oct 13 15:36 ./new/dir1/new.txt
-rw-rw-r-- 1 abhishek abhishek 35 Oct 13 15:36 ./new/dir2/another.txt
-rw-rw-r-- 1 abhishek abhishek 35 Oct 13 18:51 ./new/mystuff/new.txt
-rwxrwxrwx 1 abhishek abhishek 35 Oct 13 15:37 ./new/new.txt
-rw-rw-r-- 1 abhishek abhishek 35 Oct 13 18:16 ./new.txt
许多人忘记{} +在 exec 命令的末尾添加。您必须使用它并注意 {} 和 + 之间的空格。
{} 是引用 find 命令结果的内容。你可以把它想象成 {file 1, file 2, file 3}。该+符号用于终止 exec 命令。
还有另一个与 exec 的约定:
find . -type f -name *.txt" -exec ls -l {} \;
这里, ; 用于代替 + 符号。之前的附加; 用于转义特殊字符;。
的优点{} +是能够运行命令数量ls -l file1 file2 file3,而{} ;将运行ls -l file1,ls -l file2等等。
但是,{} ;具有{}在同一个 exec 语句中使用多次的优点,例如,下面的命令将使用 .old 扩展名重命名所有找到的文件。
find . -type f -name *.txt" -exec mv {} {}.old \;
使用 xargs
许多 Linux 用户习惯了管道重定向。这个带有尾随的 exec 命令{} +对他们来说似乎很吓人。
这是 xargs 帮助的地方,您只需通过管道将 find 命令的输出解析为xargs 命令。
find . -type f -name *.txt" | xargs ls -l
语法看起来简单多了,对吧?Xargs 命令也很强大。
结合 find 和 grep
现在您了解了将 find 与 xargs 和 exec 命令结合使用,您可以使用它来组合 find 和 grep。
对于任何系统管理员或软件开发人员,find 和 grep 是最常见但最有用的组合之一。
您使用 find 搜索文件名模式,然后使用 grep 搜索这些文件中的内容。
例如,您要搜索包含术语 Alice 的所有 .txt 文件。您可以像这样组合 find 和 grep:
find . -type f -name "*.txt" -exec grep -i alice {} +
使用 xargs 也可以实现相同的效果:
find . -type f -name "*.txt" | xargs grep -i alice
当然,这是最简单的示例,但如果您熟悉grep 命令,则可以根据自己的喜好和需要使用它。
find还有很多……
并且不可能列出所有的 find 命令选项和示例,可能性是无限的,但是当您熟悉 find 命令时,您可以开始在各种情况下使用它。这真的取决于你如何结合这里的逻辑。