除了在一个目录结构下查找文件这种基本的操做,你还能够用find命令实现一些实用的操做,使你的命令行之旅更加简易。html
本文将介绍15种不管是于新手仍是老鸟都很是有用的Linux find命令。node
首先,在你的home目录下面建立下面的空文件,来测试下面的find命令示例。linux
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
# vim create_sample_files.sh
touch
MybashProgram.sh
touch
mycprogram.c
touch
MyCProgram.c
touch
Program.c
mkdir
backup
cd
backup
touch
MybashProgram.sh
touch
mycprogram.c
touch
MyCProgram.c
touch
Program.c
# chmod +x create_sample_files.sh
# ./create_sample_files.sh
# ls -R
.:
backup MybashProgram.sh MyCProgram.c
create_sample_files.sh mycprogram.c Program.c
.
/backup
:
MybashProgram.sh mycprogram.c MyCProgram.c Program.c
|
这是find命令的一个基本用法。下面的例子展现了用MyCProgram.c做为查找名在当前目录及其子目录中查找文件的方法。程序员
1
2
3
|
# find -name "MyCProgram.c"
.
/backup/MyCProgram
.c
.
/MyCProgram
.c
|
这是find命令的一个基本用法。下面的例子展现了用MyCProgram.c做为查找名在当前目录及其子目录中查找文件的方法,忽略了大小写。shell
1
2
3
4
5
|
# find -iname "MyCProgram.c"
.
/mycprogram
.c
.
/backup/mycprogram
.c
.
/backup/MyCProgram
.c
.
/MyCProgram
.c
|
在root目录及其子目录下查找passwd文件。vim
1
2
3
4
5
|
# find / -name passwd
.
/usr/share/doc/nss_ldap-253/pam
.d
/passwd
.
/usr/bin/passwd
.
/etc/pam
.d
/passwd
.
/etc/passwd
|
在root目录及其1层深的子目录中查找passwd. (例如root — level 1, and one sub-directory — level 2)bash
1
2
|
# find -maxdepth 2 -name passwd
.
/etc/passwd
|
在root目录下及其最大两层深度的子目录中查找passwd文件. (例如 root — level 1, and two sub-directories — level 2 and 3 )ssh
1
2
3
4
|
# find / -maxdepth 3 -name passwd
.
/usr/bin/passwd
.
/etc/pam
.d
/passwd
.
/etc/passwd
|
在第二层子目录和第四层子目录之间查找passwd文件。socket
1
2
3
|
# find -mindepth 3 -maxdepth 5 -name passwd
.
/usr/bin/passwd
.
/etc/pam
.d
/passwd
|
下面的例子展现了find命令来计算全部不区分大小写的文件名为“MyCProgram.c”的文件的MD5验证和。{}将会被当前文件名取代。测试
1
2
3
4
5
|
find
-iname
"MyCProgram.c"
-
exec
md5sum {} \;
d41d8cd98f00b204e9800998ecf8427e .
/mycprogram
.c
d41d8cd98f00b204e9800998ecf8427e .
/backup/mycprogram
.c
d41d8cd98f00b204e9800998ecf8427e .
/backup/MyCProgram
.c
d41d8cd98f00b204e9800998ecf8427e .
/MyCProgram
.c
|
显示全部的名字不是MyCProgram.c的文件或者目录。因为maxdepth是1,因此只会显示当前目录下的文件和目录。
1
2
3
4
5
6
|
find
-maxdepth 1 -not -iname
"MyCProgram.c"
.
.
/MybashProgram
.sh
.
/create_sample_files
.sh
.
/backup
.
/Program
.c
|
任何一个文件都有一个独一无二的inode编号,借此咱们能够区分文件。建立两个名字类似的文件,例如一个有空格结尾,一个没有。
1
2
3
4
5
6
|
touch
"test-file-name"
# touch "test-file-name "
[Note: There is a space at the end]
# ls -1 test*
test
-
file
-name
test
-
file
-name
|
从ls的输出不能区分哪一个文件有空格结尾。使用选项-i,能够看到文件的inode编号,借此能够区分这两个文件。
1
2
3
|
ls
-i1
test
*
16187429
test
-
file
-name
16187430
test
-
file
-name
|
你能够以下面所示在find命令中指定inode编号。在此,find命令用inode编号重命名了一个文件。
1
2
3
4
5
|
find
-inum 16187430 -
exec
mv
{} new-
test
-
file
-name \;
# ls -i1 *test*
16187430 new-
test
-
file
-name
16187429
test
-
file
-name
|
你能够在你想对那些像上面同样的糟糕命名的文件作某些操做时使用这一技术。例如,名为file?.txt的文件名字中有一个特殊字符。若你想执行“rm file?.txt”,下面所示的全部三个文件都会被删除。因此,采用下面的步骤来删除”file?.txt”文件。
1
2
|
ls
file1.txt file2.txt
file
?.txt
|
找到每个文件的inode编号。
1
2
3
4
|
ls
-i1
804178 file1.txt
804179 file2.txt
804180
file
?.txt
|
以下所示:?使用inode编号来删除那些具备特殊符号的文件名。
1
2
3
4
|
find
-inum 804180 -
exec
rm
{} \;
# ls
file1.txt file2.txt
[Note: The
file
with name
"file?.txt"
is now removed]
|
下面的操做时合理的:
此例中,假设目录包含如下文件。注意这些文件的权限不一样。
1
2
3
4
5
6
7
8
|
ls
-l
total 0
-rwxrwxrwx 1 root root 0 2009-02-19 20:31 all_for_all
-rw-r--r-- 1 root root 0 2009-02-19 20:30 everybody_read
---------- 1 root root 0 2009-02-19 20:31 no_for_all
-rw------- 1 root root 0 2009-02-19 20:29 ordinary_file
-rw-r----- 1 root root 0 2009-02-19 20:27 others_can_also_read
----r----- 1 root root 0 2009-02-19 20:27 others_can_only_read
|
找到具备组读权限的文件。使用下面的命令来找到当前目录下对同组用户具备读权限的文件,忽略该文件的其余权限。
1
2
3
4
5
|
find
. -perm -g=r -
type
f -
exec
ls
-l {} \;
-rw-r--r-- 1 root root 0 2009-02-19 20:30 .
/everybody_read
-rwxrwxrwx 1 root root 0 2009-02-19 20:31 .
/all_for_all
----r----- 1 root root 0 2009-02-19 20:27 .
/others_can_only_read
-rw-r----- 1 root root 0 2009-02-19 20:27 .
/others_can_also_read
|
找到对组用户具备只读权限的文件。
1
2
|
find
. -perm g=r -
type
f -
exec
ls
-l {} \;
----r----- 1 root root 0 2009-02-19 20:27 .
/others_can_only_read
|
找到对组用户具备只读权限的文件(使用八进制权限形式)。
1
2
|
find
. -perm 040 -
type
f -
exec
ls
-l {} \;
----r----- 1 root root 0 2009-02-19 20:27 .
/others_can_only_read
|
下面命令的输出文件绝大多数都是锁定文件盒其余程序建立的place hoders
1
|
find
~ -empty
|
只列出你home目录里的空文件。
1
|
find
. -maxdepth 1 -empty
|
只列出当年目录下的非隐藏空文件。
1
|
find
. -maxdepth 1 -empty -not -name
".*"
|
下面的命令列出当前目录及子目录下的5个最大的文件。这会须要一点时间,取决于命令须要处理的文件数量。
1
|
find
. -
type
f -
exec
ls
-s {} \; |
sort
-n -r |
head
-5
|
方法同查找5个最大的文件相似,区别只是sort的顺序是降序。
1
|
find
. -
type
f -
exec
ls
-s {} \; |
sort
-n |
head
-5
|
上面的命令中,极可能你看到的只是空文件(0字节文件)。如此,你可使用下面的命令列出最小的文件,而不是0字节文件。
1
|
find
. -not -empty -
type
f -
exec
ls
-s {} \; |
sort
-n |
head
-5
|
只查找socket文件
1
|
find
. -
type
s
|
查找全部的目录
1
|
find
. -
type
d
|
查找全部的通常文件
1
|
find
. -
type
f
|
查找全部的隐藏文件
1
|
find
. -
type
f -name
".*"
|
查找全部的隐藏目录
1
|
find
-
type
d -name
".*"
|
显示在指定文件以后作出修改的文件。下面的find命令将显示全部的在ordinary_file以后建立修改的文件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
ls
-lrt
total 0
-rw-r----- 1 root root 0 2009-02-19 20:27 others_can_also_read
----r----- 1 root root 0 2009-02-19 20:27 others_can_only_read
-rw------- 1 root root 0 2009-02-19 20:29 ordinary_file
-rw-r--r-- 1 root root 0 2009-02-19 20:30 everybody_read
-rwxrwxrwx 1 root root 0 2009-02-19 20:31 all_for_all
---------- 1 root root 0 2009-02-19 20:31 no_for_all
# find -newer ordinary_file
.
.
/everybody_read
.
/all_for_all
.
/no_for_all
|
使用-size选项能够经过文件大小查找文件。
查找比指定文件大的文件
1
|
find
~ -size +100M
|
查找比指定文件小的文件
1
|
find
~ -size -100M
|
查找符合给定大小的文件
1
|
find
~ -size 100M
|
注意: – 指比给定尺寸小,+ 指比给定尺寸大。没有符号表明和给定尺寸彻底同样大。
若你发现有些东西颇有用,你能够给他取别名。而且在任何你但愿的地方执行。
经常使用的删除a.out文件。
1
2
|
alias
rmao=
"find . -iname a.out -exec rm {} \;"
# rmao
|
删除c程序产生的core文件。
1
2
|
alias
rmc=
"find . -iname core -exec rm {} \;"
# rmc
|
下面的命令删除大于100M的*.zip文件。
1
|
find
/ -
type
f -name *.zip -size +100M -
exec
rm
-i {} \;"
|
用别名rm100m删除全部大雨100M的*.tar文件。使用一样的思想能够建立rm1g,rm2g,rm5g的一类别名来删除全部大于1G,2G,5G的文件。
1
2
3
4
5
6
7
8
9
|
alias
rm100m=
"find / -type f -name *.tar -size +100M -exec rm -i {} \;"
# alias rm1g="find / -type f -name *.tar -size +1G -exec rm -i {} \;"
# alias rm2g="find / -type f -name *.tar -size +2G -exec rm -i {} \;"
# alias rm5g="find / -type f -name *.tar -size +5G -exec rm -i {} \;"
# rm100m
# rm1g
# rm2g
# rm5g
|
Find命令示例(第二部分)
前阵子,咱们审查了15件实事 find命令的例子(第一部分)。查找命令能够作不少比只是在寻找基于名称的文件 (第2部分)在这篇文章中,让咱们来讨论15高级find命令的例子, 包括-根据它访问,修改或改变的时间查找文件,查找文件相比之下,执行操做找到的文件等, 拉梅什纳塔拉詹:这是个人照片中的可爱的小女儿。她很高兴地发如今加州长滩水族馆海狮。
你能够找到基于如下三个文件的时间属性的文件。
在下面的例子中,min选项之间的差别和时间选项是参数。
想要经过文件修改时间找出文件,可使用参数 -mmin -mtime。下面是man手册中有关mmin和mtime的定义。
执行下面例子中的命令,将会找到当前目录以及其子目录下,最近一次修改时间在1个小时(60分钟)以内的文件或目录
1
|
# find . -amin -60
|
一样的方式,执行下面例子中的命令,将会找到24小时(1天)内被访问了的文件(文件系统根目录 / 下)
1
|
# find / -atime -1
|
想要经过文件访问时间找出文件,可使用参数 -amin -atime。下面是man手册中有关amin和atime的定义。
执行下面例子中的命令,将会找到当前目录以及其子目录下,最近一次访问时间在1个小时(60分钟)以内的文件或目录
1
|
# find . -amin -60
|
一样的方式,执行下面例子中的命令,将会找到24小时(1天)内被访问了的文件(文件系统根目录 / 下)
1
|
# find / -atime -1
|
(译者注:这里的改变动第1个例子的更改文件内容时间是不一样概念,这里是更改的是文件inode的数据,好比文件的权限,所属人等等信息)
要查找文件的inode的更改时间,使用-cmin和-ctime选项
(译者注:若是上面的n为-n形式,则表示n分钟/天以内,n为+n则表示n分钟/天以前)
下面的例子在当前目录和其子目录下面查找一个小时内文件状态改变的文件(也就是60分钟内):
1
|
# find . -cmin -60
|
一样的道理,下面的例子在根目录/及其子目录下一天内(24小时内)文件状态被改变的文件列表:
1
|
# find / -ctime -1
|
例4:搜索仅仅限定于文件,不显示文件夹
上面的例子搜索出来不只仅有文件,还会显示文件夹。由于当一个文件被访问的时候,它所处的文件夹也会被访问,若是你对文件夹不感兴趣,那么可使用 -type f 选项
下面的例子会显示30分钟内被修改过的文件,文件夹不显示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
# 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
[注: 上面的输出包含了文件和文件夹]
# find /etc/sysconfig -amin -30 -type f
.
/i18n
.
/networking/profiles/default/resolv
.conf
.
/networking/profiles/default/hosts
[注: 上面的输出仅仅包含文件]
|
例5: 仅仅查找非隐藏的文件(不显示隐藏文件):
若是咱们查找的时候不想隐藏文件也显示出来,可使用下面的正则式查找:
下面的命令会显示当前目录及其子目录下15分钟内文件内容被修改过的文件,而且只列出非隐藏文件。也就是说,以.开头的文件时不会显示出来的
1
|
# find . -mmin -15 <span class="MathJax_Preview">\( ! -regex ".*/\..*" \)</span><script type="math/tex"> ! -regex ".*/\..*" </script>
|
基于文件比较的查找命令
咱们平时经过更别的东西进行比较,会更容易记住一些事情。好比说我想找出在我编辑test文件以后编辑过的文件。你能够经过test这个文件的编辑时间做为比较基准去查找以后编辑过的文件:
例6: 查找文件修改时间在某一文件修改后的文件:
1
|
语法:
find
-newer FILE
|
下面的例子显示在/etc/passwd修改以后被修改过的文件。对于系统管理员,想知道你新增了一个用户后去跟踪系统的活动状态是颇有帮助的(万一那新用户不老实,一上来就乱搞,你很快就知道了 ^_^):
1
|
# find -newer /etc/passwd
|
例7:查找文件访问时间在某一文件的修改时间以后的文件:
1
|
# find -newer /etc/passwd
|
下面的例子显示全部在/etc/hosts文件被修改后被访问到的文件。若是你新增了一个主机/端口记录在/etc/hosts文件中,你极可能很想知道在那以后有什么文件被访问到了,下面是这个命令:
1
|
# find -anewer /etc/hosts
|
例8:查找状态改变时间在某个文件修改时间以后的文件:
1
|
语法:
find
-cnewer FILE
|
下面的例子显示在修改文件/etc/fstab以后全部文件状态改变过的文件。若是你在/etc/fstab新增了一个挂载点,你极可能想知道以后哪些文件的状态发生了改变,这时候你可使用以下命令:
1
|
# find -cnewer /etc/fstab
|
在查找到的文件列表结果上直接执行命令:
这以前你已经看到了若是经过find命令去查找各类条件的文件列表。若是你对这些find命令还不熟悉,我建议你看完上面的第一部分
接下来这部分咱们向你介绍若是在find命令上执行各类不一样的命令,也就是说如何去操做find命令查找出来的文件列表。
咱们能在find命令查找出来的文件名列表上指定任意的操做:
1
|
# find <CONDITION to Find files> -exec <OPERATION> \;
|
其中的OPERATION能够是任意的命令,下面列举一下比较经常使用的:
1
2
3
4
5
6
7
|
# 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:仅仅在当前文件系统中搜索
系统管理员有时候仅仅想在/挂载的文件系统分区上搜索,而不想去搜索其余的挂载分区,好比/home/挂载分区。若是你有多个分区被挂载了,你想在/下搜索,通常能够按下面的这样作
下面这个命令会搜索根目录/及其子目录下全部.log结尾的文件名。若是你有多个分区在/下面,那么这个搜索会去搜索全部的被挂载的分区:
1
|
# find / -name "*.log"
|
若是咱们使用-xdev选项,那么仅仅会在在当前文件系统中搜索,下面是在xdev的man page上面找到的一段-xdev的定义:
下面的命令会在/目录及其子目录下搜索当前文件系统(也就是/挂载的文件系统)中全部以.log结尾的文件,也就是说若是你有多个分区挂载在/下面,下面的搜索不会去搜索其余的分区的(好比/home/)
1
|
# find / -xdev -name "*.log"
|
例11: 在同一个命令中使用多个{}
linux手册说命令中只能使用一个{},不过你能够像下面这样在同一个命令中使用多个{}
1
|
# find -name "*.txt" cp {} {}.bkup \;
|
注意,在同一个命令中使用这个{}是能够的,可是在不一样的命令里就不行了,也就是说,若是你想象下面这样重命名文件是行不通的
1
|
find
-name
"*.txt"
-
exec
mv
{} `
basename
{} .htm`.html \;
|
例12: 使用多个{}实例
你能够像下面这样写一个shell脚本去模拟上面那个重命名的例子
1
|
# mv "$1" "`basename "$1" .htm`.html"
|
上面的双引号是为了防止文件名中出现的空格,不加的话会有问题。而后你把这个shell脚本保存为mv.sh,你能够像下面这样使用find命令了
1
|
find
-name
"*.html"
-
exec
.
/mv
.sh
'{}'
\;
|
因此,任何状况下你在find命令执行中想使用同一个文件名屡次的话,先写一个脚本,而后在find中经过-exec执行这个脚本,把文件名参数传递进去就行,这是最简单的办法
例13: 将错误重定向到/dev/nul
重定向错误输出通常不是什么好的想法。一个有经验的程序员懂得在终端显示错误并及时修正它是很重要的。
尤为是在find命令中重定向错误不是个好的实践。 可是若是你确实不想看到那些烦人的错误,想把错误都重定向到null设备中(也就是linux上的黑洞装置,任何丢进去的东西消失的无影无踪了)。你能够像下面这样作
1
|
find
-name
"*.txt"
2>>
/dev/null
|
有时候这是颇有用的。好比,若是你想经过你本身的帐号在/目录下查找全部的*.conf文件,你会获得不少不少的”Permission denied”的错误消息, 就像下面这样:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
$
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]
|
1
2
3
4
|
$
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(类Unix)系统里面是很很差的。你可使用find而后后面加上rename命令的替换功能去重命名这些文件,将空格转换成下划线
下面显示怎样将全部mp3文件的文件名中的空格换成_
1
|
$
find
. -
type
f -iname “*.mp3″ -
exec
rename “s/
/_/g
” {} \;
|
例15: 在find结果中同时执行两条命令
在find的man page页面中,下面是一次文件查找遍历中使用两条命令的语法举例
下面的find命令的例子,遍历文件系统一次,列出拥有setuid属性的文件和目录,写入/root/suid.txt文件, 若是文件大小超过100M,将其记录到/root/big.txt中
1
2
|
# find / <span class="MathJax_Preview">\( -perm -4000 -fprintf /root/suid.txt '%#m %u %p\n' \)</span><script type="math/tex"> -perm -4000 -fprintf /root/suid.txt '%#m %u %p\n' </script> , \
<span class=
"MathJax_Preview"
>\( -size +100M -fprintf
/root/big
.txt
'%-10s %p\n'
\)<
/span
><script
type
=
"math/tex"
> -size +100M -fprintf
/root/big
.txt
'%-10s %p\n'
<
/script
>
|
原文地址:http://www.thegeekstuff.com/2009/03/15-practical-linux-find-command-examples/