如何将 find 命令与 exec 结合使用
Linux 中的 find命令是一个根据给定条件查找文件和目录的绝佳工具。
您可以通过对找到的文件实际执行特定操作将您的发现提升到一个新的水平。
例如,你找到了所有带有 .jpeg 扩展名的文件。如何将它们重命名为 .jpg 扩展名?
您不能直接将 find 命令的输出通过管道重定向到另一个命令。这样不行。
有两种方法可以对 find 命令的结果执行其他命令:
- 使用 xargs
- 使用 exec
关于 xargs 命令已经有了详细的文章。本教程将重点介绍如何结合使用 find 和 exec 命令。
将 exec 命令与 find 命令的输出结合使用
使用 exec 执行 find 的基本语法如下:
find [path] [arguments] -exec [command] {} \;
以下是一个简单的解释:
- [command]是您想要对 find 命令给出的结果执行的命令。
- {}是一个占位符,用于保存 find 命令给出的结果。
- \;表示对于每个找到的结果,执行[命令] 。您需要在此处转义 ;,因此转义 \;。
还有一种语法与上面的略有不同,如下所示:
find [path] [arguments] -exec [command] {} +
这里,+表示对于 find 命令的每个结果,[command] 仅执行一次。所有结果都作为参数一起传递给 [command]。+
不需要用进行转义\+
。
{} \;
仍然不清楚and的用法{} +
?
{} \;
是这样的(对每个找到的结果执行命令):
ls file1.txt
ls file2.txt
ls file3.txt
{} +
是这样的(使用所有结果参数执行一次命令):
ls file1.txt file2.txt file3.txt
虽然在这里使用似乎{} +
是更好的选择,但事实恰恰相反。如果 find 命令抛出 50 个结果,则您无法将它们全部作为参数一起传递,因为命令行的最大长度存在限制。
{} \;
这就是为什么除非您确切知道自己需要什么,否则最好这样做。
结合 find 和 exec 命令的实际示例
让我分享一些 find exec 命令的常见示例,以便您更好地理解它们。
1.查找并显示文件属性
在 find exec 命令的第一个简单示例中,我将显示 /tmp 目录下的所有锁文件并显示它们的属性。
sudo find /tmp/ -type f -name *lock -exec ls -l {} \;
结果如下:
sagar@LHB:~$ sudo find /tmp/ -type f -name *lock -exec ls -l {} \;
-r--r--r-- 1 gdm gdm 11 Jul 17 08:01 /tmp/.X1024-lock
-r--r--r-- 1 gdm gdm 11 Jul 17 08:01 /tmp/.X1025-lock
2. 查找并重命名文件
是的,使用 find 和 exec 可以轻松重命名文件。mv命令用于重命名文件。我也会这样做。
sudo find /home/sagar/Downloads/ -type f -name 'ubuntu*' -exec mv {} {}_renamed \;
上述命令查找以名称 ubuntu 开头的文件并将它们存储在占位符中。将结果存储在占位符中的过程完成后,它将在占位符中存储的每个文件的末尾添加“_renamed”。
3. 收集并存储文件大小
在这个例子中,我将向您展示如何收集某个目录下可用文件的大小并创建一个文件来保存给定的输出。
我将收集 /tmp 目录下每个文件的大小,并将输出保存在 /root 目录下,文件名为 du_data.out
sudo find /tmp/ -type f -exec du -sh {} \; > /root/du_data.out
现在,我们来看看/root目录下最近创建的文件是什么样的。
4. 删除具有特定参数的文件
自动删除文件时请格外小心。如果不注意,可能会造成灾难性的后果。要么使用交互式删除,rm -i
要么先查看 find 命令的结果。
find exec 命令组合的另一个常见示例是查找大于特定大小的文件并将其删除。如果您正在清理旧日志,这种方法很有效。
为了演示,我正在删除桌面目录下大于 100 MB 的文件。
find ~/Desktop -size +100M -exec rm {} \;
同样,您还可以根据文件的时间长短来删除文件。例如,让我们删除超过 10 天的文件。
sudo find /tmp/ -type f -mtime +10 -exec rm {} \;
这里我使用了 -mtime 来标识过去 24 小时内修改的数据,当与 +10 配对时,它会找到并删除超过 10 天的文件。
5. 执行特定工具
在各种情况下,您可能希望在找到文件后启动某些工具或包。
例如,当我搜索任何 mp3 文件时,我想要运行 id3v2,它将带来有关找到的 mp3 文件的详细信息。
find . -name "*.mp3" -exec id3v2 -l {} \;
id3v2 是一个显示有关 mp3 文件详细信息的包,-l 用于显示与找到的 mp3 相关的每个 mp3 标签。
6.更改文件和目录的所有权
更改文件和目录的所有权是 find 和 exec 的组合多么强大的另一个例子。
在这里,我正在寻找名为 的用户拥有的文件sagar
,然后将其所有权更改为milan
。
sudo find /home/sagar/disk/Downloads -user sagar -type f -exec chown milan {} \;
7. 更改文件权限
那么如何使用 find 和 exec 更改文件的权限?
sudo find /home/sagar/disk/Downloads -type f -exec chmod 644 {} \;
在上面的命令中,我使用了 -type f,因此该命令将仅适用于给定目录下的文件。
8. 收集每个文件的 md5sum
在此示例中,我将演示如何收集 /tmp 目录下每个可用文件的 md5sum。
sudo find /tmp/ -type f -exec md5sum {} \;
如您所见,应用的命令收集了每个可用文件的 md5sum,包括其名称和 md5sum。
但是如果你想要保存这个输出并且直接用不同的名称保存,那该怎么办呢?你只需要按照给定的命令并直接更改相应的名称:
sudo find /tmp/ -type f -exec md5sum {} \; > /Documents/checksumdata.out
9. 将 exec 与 grep 命令结合使用
find 命令作用于文件名。grep 命令作用于文件的内容。
将 find 和 grep 与 exec 结合起来,您就得到了 Linux 命令行中强大的搜索工具。
例如,下面的命令搜索所有带有.hbs
扩展名的文件。使用 grep,它会在这些 .hbs 文件的内容中搜索字符串“excerpt”。
find . -type f -name "*.hbs" -exec grep -iH excerpt {} \;
使用该-H
选项,grep 命令将显示每个匹配的文件名。以下是输出:
sagar@LHB:~/Downloads/casper-hyvor$ find . -type f -name "*.hbs" -exec grep -iH excerpt {} \;
./author.hbs: <div class="post-card-excerpt">{{bio}}</div>
./partials/post-card.hbs: {{#if excerpt}}
./partials/post-card.hbs: <div class="post-card-excerpt">{{excerpt}}</div>
./post.hbs: {{#if custom_excerpt}}
./post.hbs: <p class="article-excerpt">{{custom_excerpt}}</p>
./tag.hbs: <div class="post-card-excerpt">
附加提示:使用多个 exec 命令进行查找
是的,您可以使用单个 find 命令链接多个 exec 命令。
让我采用您在上一节中看到的相同示例并使用两个 exec 命令。
find . -type f -name "*.hbs" -exec echo {} \; -exec grep excerpt {} \;
它会先搜索 .hbs 文件,然后用第一个 exec 命令回显其名称。然后,会搜索这些文件以查找“摘录”字符串。
输出与上一个命令的输出略有不同:
sagar@LHB:~/Downloads/casper-hyvor$ find . -type f -name "*.hbs" -exec echo {} \; -exec grep excerpt {} \;
./index.hbs
./page.hbs
./default.hbs
./author.hbs
<div class="post-card-excerpt">{{bio}}</div>
./error-404.hbs
./error.hbs
./partials/icons/twitter.hbs
./partials/icons/fire.hbs
./partials/icons/lock.hbs
./partials/icons/loader.hbs
./partials/icons/rss.hbs
./partials/icons/avatar.hbs
./partials/icons/facebook.hbs
./partials/post-card.hbs
{{#if excerpt}}
<div class="post-card-excerpt">{{excerpt}}</div>
./post.hbs
{{#if custom_excerpt}}
<p class="article-excerpt">{{custom_excerpt}}</p>
./tag.hbs
<div class="post-card-excerpt">
结论
Find 是一个功能强大的命令,可以根据多个条件搜索文件。exec 命令可让您处理 find 命令的结果。
我在这里分享的示例只是冰山一角。find-exec 命令组合为您提供了在 Linux 命令行中执行操作的无限可能性。