上一次,我们回顾了 15 个实用的find 命令示例(第一部分)。Find 命令可以做的不仅仅是根据名称搜索文件。
在本文(第 2 部分)中,让我们讨论find 命令的15 个高级示例,包括——根据访问、修改或更改的时间查找文件、比较查找文件、对找到的文件执行操作等,
根据访问/修改/更改时间查找文件
您可以根据以下三个文件时间属性查找文件。
- 文件的访问时间。访问时间在文件访问时更新。
- 文件的修改时间。当文件内容被修改时,修改时间会更新。
- 更改文件的时间。当inode 数据更改时,更改时间会更新。
在以下示例中,min 选项和time 选项之间的区别在于参数。
- min 参数将其参数视为minutes。例如,分钟 60 = 60 分钟(1 小时)。
- time 参数将其参数视为24 hours。例如,时间 2 = 2*24 小时(2 天)。
- 在进行24小时计算时,小数部分被忽略,因此25小时被视为24小时,47小时也被视为24小时,只有48小时被视为48小时。要获得更清晰的信息,请参阅find 命令手册页的 -atime 部分。
示例 1:查找内容在过去 1 小时内更新的文件
要根据内容修改时间查找文件,请使用选项 -mmin 和 -mtime。以下是手册页中 mmin 和 mtime 的定义。
- -mmin n文件的数据在n 分钟前最后一次修改。
- -mtime n文件的数据最后修改时间为n*24 小时前。
以下示例将查找当前目录和子目录中的文件,其内容在过去 1 小时(60 分钟)内更新
# find . -mmin -60
以同样的方式,以下示例查找在过去 24 小时(1 天)内更新的所有文件(在根文件系统 / 下)。
# find / -mtime -1
示例 2:查找 1 小时前访问过的文件
要根据文件访问时间查找文件,请使用选项 -amin 和 -atime。以下是 find 手册页中 amin 和 atime 的定义。
- -amin n上次访问文件n 分钟前
- -atime n上次访问文件n*24 小时前
以下示例将在当前目录和子目录中查找最近 1 小时(60 分钟)内访问过的文件
# find -amin -60
以同样的方式,以下示例查找过去 24 小时(1 天)内访问过的所有文件(在根文件系统 / 下)。
# find / -atime -1
示例 3:查找恰好在 1 小时之前更改的文件
要根据文件 inode 更改时间查找文件,请使用选项 -cmin 和 -ctime。以下是 find 手册页中 cmin 和 ctime 的定义。
- -cmin n文件的状态在n 分钟前最后一次更改。
- -ctime n文件的状态在n*24 小时前最后一次更改。
以下示例将查找当前目录和子目录中的文件,这些文件在过去 1 小时(60 分钟)内发生变化
# find . -cmin -60
以同样的方式,以下示例查找在过去 24 小时(1 天)内发生更改的所有文件(在根文件系统 / 下)。
# find / -ctime -1
示例 4:将查找输出仅限于文件。(仅将文件显示为查找命令结果)
上面的 find 命令还将显示目录,因为当访问其中的文件时,目录也会被访问。但是,如果您只想显示文件,则在 find 命令中输入 -type f 作为
以下find 命令显示在过去 30 分钟内访问过的文件。
# find /etc/sysconfig -amin -30
.
./console
./network-scripts
./i18n
./rhn
./rhn/clientCaps.d
./networking
./networking/profiles
./networking/profiles/default
./networking/profiles/default/resolv.conf
./networking/profiles/default/hosts
./networking/devices
./apm-scripts
[Note: The above output contains both files and directories]
# find /etc/sysconfig -amin -30 -type f
./i18n
./networking/profiles/default/resolv.conf
./networking/profiles/default/hosts
[Note: The above output contains only files]
示例 5:将搜索限制为仅未隐藏的文件。(不要在查找输出中显示隐藏文件)
当我们不希望在查找输出中列出隐藏文件时,我们可以使用以下正则表达式。
下面的查找显示了在过去 15 分钟内修改过的文件。它只列出未隐藏的文件。即以 . 开头的隐藏文件。(句点)不会显示在查找输出中。
# find . -mmin -15 \( ! -regex ".*/\..*" \)
使用 Find 命令比较查找文件
人类的大脑可以通过参考更好地记住事情,例如,我想找到我在编辑文件“test”后编辑过的文件。您可以通过参考其他文件修改来查找文件,如下所示。
示例 6:查找修改特定 FILE 后修改的文件
Syntax: find -anewer FILE
以下示例显示了修改 /etc/passwd 文件后修改的所有文件。如果您想跟踪添加新用户后所做的所有活动,这会很有帮助。
# find -newer /etc/passwd
示例 7:查找修改特定 FILE 后访问的文件
Syntax: find -anewer FILE
下面的例子显示了修改 /etc/hosts 后访问的所有文件。如果您记得在 /etc/hosts 中添加了一个条目并希望查看从那时起您访问过的所有文件,请使用以下命令。
# find -anewer /etc/hosts
示例 8:查找在修改特定 FILE 后状态发生更改的文件。
Syntax: find -cnewer FILE
以下示例显示修改 /etc/fstab 后状态改变的所有文件。如果您记得在 /etc/fstab 中添加了一个挂载点,并且想知道从那时起状态发生变化的所有文件,请使用以下命令。
find -cnewer /etc/fstab
对通过 Find 命令找到的文件执行任何操作
我们已经在本文和上一篇文章中研究了使用find 命令查找文件的许多不同方法。如果您不熟悉不同方式查找文件,我强烈建议您阅读第 1 部分。
本节介绍如何通过 find 命令对文件进行不同的操作。即如何操作由 find 命令输出返回的文件。
我们可以对从 find 命令找到的文件指定任何操作。
find <CONDITION to Find files> -exec <OPERATION> \;
操作可以是任何东西,例如:
- rm 命令删除 find 命令找到的文件。
- mv 命令重命名找到的文件。
- ls -l 命令获取 find 命令输出文件的详细信息。
- find 命令输出文件上的md5sum
- wc 命令计算 find 命令输出文件上的总字数。
- 在 find 命令输出文件上执行任何Unix shell 命令。
- 或在查找命令输出文件上执行您自己的自定义 shell 脚本/命令。
示例 9:查找命令输出中的 ls -l。列出过去 1 小时内编辑过的文件。
# find -mmin -60
./cron
./secure
# find -mmin -60 -exec ls -l {} \;
-rw------- 1 root root 1028 Jun 21 15:01 ./cron
-rw------- 1 root root 831752 Jun 21 15:42 ./secure
示例 10:仅在当前文件系统中搜索
系统管理员可能希望在根文件系统中进行搜索,而不是在其他已安装的分区中进行搜索。当您挂载了多个分区时,如果您想在 / 中搜索。您可以执行以下操作。
以下命令将从 / 开始搜索 *.log 文件。即如果您在 / (root) 下挂载了多个分区,以下命令将搜索所有这些挂载的分区。
# find / -name "*.log"
这将仅在当前文件系统中搜索文件。以下是 find 手册页中的 xdev 定义:
- -xdev不要下降其他文件系统上的目录。
以下命令将从 / (root) 开始并仅在当前文件系统中搜索 *.log 文件。即如果您在 / (root) 下安装了多个分区,以下命令将不会搜索所有这些安装的分区。
# find / -xdev -name "*.log"
示例 11:在同一命令中使用多个 { }
手册说只有一个 {} 实例是可能的。但是您可以在同一命令中使用多个 {},如下所示。
# find -name "*.txt" cp {} {}.bkup \;
在同一命令中使用此 {} 是可能的,但在不同的命令中使用它是不可能的,假设您想按如下方式重命名文件,这不会给出预期的结果。
find -name "*.txt" -exec mv {} `basename {} .htm`.html \;
示例 12:在多个实例中使用 { }。
您可以通过编写如下所示的 shell 脚本来模拟它。
# mv "$1" "`basename "$1" .htm`.html"
这些双引号用于处理文件名中的空格。然后从find 命令调用该 shell 脚本,如下所示。
find -name "*.html" -exec ./mv.sh '{}' \;
因此,无论出于何种原因,如果您希望多次使用相同的文件名,那么编写简单的 shell 脚本并将文件名作为参数传递是最简单的方法。
示例 13:将错误重定向到 /dev/null
重定向错误不是一个好习惯。有经验的用户理解在终端上打印错误并修复它的重要性。
特别是在 find 命令中重定向错误不是一个好习惯。但是,如果您不想看到错误并希望将其重定向到 null,请按如下所示进行操作。
find -name "*.txt" 2>>/dev/null
有时这可能会有所帮助。例如,如果您试图从您的帐户中查找 / (root) 下的所有 *.conf 文件,您可能会收到很多“权限被拒绝”的错误消息,如下所示。
$ find / -name "*.conf"
/sbin/generate-modprobe.conf
find: /tmp/orbit-root: Permission denied
find: /tmp/ssh-gccBMp5019: Permission denied
find: /tmp/keyring-5iqiGo: Permission denied
find: /var/log/httpd: Permission denied
find: /var/log/ppp: Permission denied
/boot/grub/grub.conf
find: /var/log/audit: Permission denied
find: /var/log/squid: Permission denied
find: /var/log/samba: Permission denied
find: /var/cache/alchemist/printconf.rpm/wm: Permission denied
[Note: There are two valid *.conf files burned in the "Permission denied" messages]
因此,如果您只想查看find 命令的实际输出而不是“权限被拒绝”错误消息,您可以将错误消息重定向到 /dev/null,如下所示。
$ find / -name "*.conf" 2>>/dev/null
/sbin/generate-modprobe.conf
/boot/grub/grub.conf
[Note: All the "Permission denied" messages are not displayed]
示例 14:将文件名中的空格替换为下划线。
您从互联网上下载的音频文件大多带有空格。但是在文件名中包含空格对于 Linux 类型的系统并不是那么好。您可以使用如下所示的 find 和 rename 命令组合来重命名文件,方法是用下划线替换空格。
以下将所有 *.mp3 文件中的空格替换为 _
$ find . -type f -iname “*.mp3″ -exec rename “s/ /_/g” {} \;
示例 15:同时执行两个查找命令
如其手册页中的 find 命令示例所示,以下是可用于在单次遍历中执行两个命令的语法。
下面的 find 命令示例,只遍历文件系统一次,将 setuid 文件和目录列出到 /root/suid.txt 中,将大文件列出到 /root/big.txt 中。
# find / \( -perm -4000 -fprintf /root/suid.txt '%#m %u %p\n' \) , \
\( -size +100M -fprintf /root/big.txt '%-10s %p\n' \)