Linux入门之Find文件查找命令
在liunx中有很多文件查找工具,但是最常用的却是locate和find命令,他们都有多种条件进行文件搜索,当然各自也有不同的特点。
locate 命令:
原理:此命令查询文件的准确度依赖于系统上预建的文件索引数据库文件:
/var/lib/mlocate/mlocate.db
[[email protected] ~]# ls -l /var/lib/mlocate/mlocate.db -rw-r-----. 1 root slocate 2135734 Aug 12 03:30 /var/lib/mlocate/mlocate.db
索引的构建:
索引的构建实在系统较为空闲时自动进行的周期性任务,当然系统管理员也可以手动更新和删除数据库(一般使用updatedb命令)。
索引的构建过程需要遍历整个根文件系统,因此相当消耗系统资源
locate命令查找特点:
查找速度快
模糊查找
非实时查找
且搜索的是对文件的全路径,不仅仅是针对文件名
可能只是针对搜索用户具备读取和执行权限的目录
locate命令用法:
locate [option] keyword
option:
-i : 执行时区分关键字大小写
-n # : 只列举最前#个匹配项的匹配文件
-r reg : 通过匹配正则表达式来匹配
例如:
通过关键字进行模糊查找
[[email protected] ~]# locate foo | wc -l #查找当前系统下多少个含有foo关键字的文件 6223 [[email protected] ~]# locate foo | head -n 5 #因为上面统计搜索出6223行,这里只显示5行 /etc/foomatic /etc/foomatic/defaultspooler /etc/foomatic/filter.conf /usr/bin/foomatic-combo-xml /usr/bin/foomatic-compiledb
解析:查找速度特别快,但是并非实时搜索,可能对于某些刚刚建立的文件搜素不到。这时可以使用updatedb命令或者删除索引文件,再使用updatedb命令重新遍历创建
通过正则表达式模式匹配查找
[[email protected] ~]# locate -r "\.sh$" #通过正则表达式来查询所有脚步文件 /etc/X11/xinit/xinitrc.d/00-start-message-bus.sh /etc/X11/xinit/xinitrc.d/50-xinput.sh /etc/X11/xinit/xinitrc.d/localuser.sh
缺点:对当前文件系统进行查询,却不能指定路径进行精确匹配查询,当然,针对这个问题也是有解决方法的,那么就借助上面的方法进行查询:
通过正则表达式来匹配对应路径
[[email protected] ~]# locate -r "^/root/ch.*\.sh" #虽然没有指定路径的条件,但是正则却能完成 /root/checkdisk.sh /root/checkint.sh
解析:从上一个例子可以看出,查找出来的都是一行一行的文件全路径,那么把全路径当作一个字符串进行精确匹配同样也可以达到效果,当然也可能查找不到,这时就需要下面的更新或重建文件索引数据库了:
通过updatedb命令来更新或者创建最新的索引文件以确保locate查询的准确性:
[[email protected] ~]# rm -f /var/lib/mlocate/mlocate.db #直接删除索引库,可以不删除 [[email protected] ~]# updatedb #这里因为是删除,所有就是重新遍历库文件了 [[email protected] ~]# ls -l /var/lib/mlocate/ #查询索引库重新生成了 total 2096 -rw-r-----. 1 root slocate 2145895 Aug 12 19:07 mlocate.db
解析:一般情况下不会去手动更新或者构建数据库,当然locate命令在实际中也并不是用来查询所有文件的,但是因为有索引库的存在,所以可以用来查询常见的系统及服务的配置文件,因为这类文件的位置一般不会改变。再加上locate 依赖于库文件,所以查找这些配置信息文件速度相对会很快,但是对于日志文件时常变化就不太好适用了。
find 命令
特征:是一个可以实时查找搜索的工具,通过遍历指定路径完成文件查找。
使用特性:
查询速度相比locate工具较慢
可以更精确的查找
实时的查找
可以按特定且多样的条件指定搜索
可能只是搜索用户具备读取和执行权限的的目录
用法:
find [option]... /patn/to/file [where] [action]
path:指定查找的具体路径,不指定默认为当前目录下
where:指定的查询条件,可以是文件名、文件大小、文件权限、文件属组等权限,不指定默认会查找指定目录下的所有文件以及子目录下的所有文件
action:对指定好的条件匹配后,后面跟特定的动作,对前面指定的条件的文件列表做一些查找,可以是打印路径、文件信息列表,默认不指定动作为显示所有匹配条件的文件路径
where(查找的常用条件):
根据文件名和inode查找:
-name “文件名关键字”:支持使用基于glob 设定文件通配符
文件通配符:* ,?,[],[^] 详细信息可以查询man 7 glob命令查询帮助
-iname “文件名关键字”:不区分字母大小写
-inum # :按照指定的inode编号进行查找对应编号的指定文件,#为inode编号
-samefile [filename]:通过指定的文件名来查询与其inode编号相同的文件
-links # :查询链接数为#的文件
-regex “PATTERN”:以PATTERN(正则表达式或关键字符)进行匹配整个文件路径字符串,不仅仅是针对文件名称,可能还有路径、属性等
根据文件的属主、属组查找:
-user [username]:查询属主为指定用户(UID)的文件
-group [groupname]:查询属组为指定用户组(GID)的文件
-uid [user_id]: 查询属主为指定的UID号的文件
-gid [group_id]: 查找属组为指定的GID号的文件
-nouser:查询没有属组的文件(比如属组位为空或只显示UID)
-nogroup:查找没有属组的文件
注意:这里的通过用户名、属组名,在查询时实际上是先去找用户或组的ID号进行查询,而不是真正通过用户或组的名称进程搜索,下面一个例子来证明:
[[email protected] ~]# useradd u1 #添加一个新用户 [[email protected] ~]# id -u u1 #显示出此新用户的UID 501 [[email protected] ~]# id u1 #显示出用户的详细编号及对应名称 uid=501(u1) gid=501(u1) groups=501(u1) [[email protected] ~]# useradd -u 501 -o u2 #这里再创建一个用户并强制设和u1相同的UID [[email protected] ~]# id u2 #显示出u2的id号和u1的一样 uid=501(u1) gid=502(u2) groups=501(u1) #因为默认一般不指定情况,新建的用户默认都会在/home目录下创建各种的家目录 [[email protected] ~]# find /home -user u1 #这里通过username进行查询 /home/u2 /home/u2/.bash_logout /home/u2/.bash_profile /home/u2/.gnome2 /home/u2/.bashrc /home/u2/.mozilla /home/u2/.mozilla/extensions /home/u2/.mozilla/plugins /home/u1 /home/u1/.bash_logout /home/u1/.bash_profile /home/u1/.gnome2 /home/u1/.bashrc /home/u1/.mozilla /home/u1/.mozilla/extensions /home/u1/.mozilla/plugins
说明:从上面可以明显的看到虽然指定的用户名是u1,但是u2的家目录文件也被查询出来,那么为了彻底证明查询是按照uid查询,这里我们再次查询对指定属主u2进行查询:
[[email protected] ~]# find /home -user u2 /home/u2 /home/u2/.bash_logout /home/u2/.bash_profile /home/u2/.gnome2 /home/u2/.bashrc /home/u2/.mozilla /home/u2/.mozilla/extensions /home/u2/.mozilla/plugins /home/u1 /home/u1/.bash_logout /home/u1/.bash_profile /home/u1/.gnome2 /home/u1/.bashrc /home/u1/.mozilla /home/u1/.mozilla/extensions /home/u1/.mozilla/plugins
解析:现在已经可以完全证明了find -user或者-group 虽然是根据指定的名称当参数,但是内部已经是按照用户名或组名对应的ID进行查询,如果UID或者GID存在一样的条目,那么通过任意相同的名称都会同时匹配
根据文件类型查询:
-type TYPE:
f 普通文件
d 目录文件
l 符号链接文件
s 套接字文件
b 块设备文件
c 字符设备文件
p 管道文件
条件的组合用法:
与:-a (注意与的优先级要高于或,前后位置不同可能条件也会有所变化)
或:-o
非:-not , !
德摩根定律:
非A 或 非B = 非(A 并 B)
非A 且 非B = 非(A 或 B)
例如:! -user u1 -a ! -user u2 = ! (-user u1 -o -user u2)
! -user u1 -o ! -user u2 = ! (-user u1 -a -user u2)
举例说明:
单个条件
find -name aa.jpg #搜索文件名为aa.jpg 的文件 find -iname aa.jpg #不区分大小写同时搜索aa.jpg AA.jpg AA.JPG等文件 find / -name “*test*” #搜索当前系统下文件名中包含test字符的文件 find /var -name “*.sh” #搜索/var的后缀为.sh脚步文件 find -user u1 -group u1 #搜索文件属主和属组名称相同的文件
多个条件
find -user u1 -not -group u1 #查询属主为u1但属组不为u1的文件 find -user u1 -o -user u2 #查询属主为u1或者u2的文件 find -not \( -user u1 -o -user u2 \) #查询用户属组非u1和u2的文件 find -not -user u1 -a -not -user u2 #等价于上面带括号的写法 find / -user u1 -o -uid 500 #属组名称为u1或者uid为500的文件
#查询/tmp 目录下,属主不是root ,且文件名不以f开头的文件
方法一:
find /tmp \( -not -user root -a -not -name "f*" \) -ls
解析:因为后面的 -ls 动作默认会取最后一个条件作为显示结果,所有这里使用括号进行包裹,注意,这里的()需要用\转义,然后括号里内开头和结尾都要空格隔开
方法二:
find /tmp -not \( -user root -o -name "f*" \) -ls
解析:遵循摩格定律,这里属主不是root 并且文件名不以f开头,那么换位等价的摩根定律就要反过来,及
-not \( 条件1 或者 条件2 \)
安装文件大小进行查找:
-szie [+|-][unit]
unit表示单位,常用有:k,M,G
#k :(#-1, #] 表示知道大小单位减去一个单位,然后取之间
如:3k 表示 2K+ 到 3K,其中不包括2K整
-#k :(0,#-1) 表示从0k一直到#-1k
如:-3k 表示 0k到3K以内
+#k :(#,∞) 表示#K以及#K以上
如:+3K 表示6K+
根据文件时间属性查询:
以天(day)为单位
-atime [+|-]#, 访问时间
#:表示#天以及#+1天
+#:#天、#+1天及以上
-#:0天到#天
-mtime 内容修改时间
-ctime 文件属性修改时间
以分钟(min)为单位:
-amin -mmin -cmin
根据文件权限位数值查询:
-perm [/|-] MODE
MODE:精确匹配每个权限位都必须符合
/MODE:只要(u,g,o)有一类权限位包含有指定权限就匹配
-MODE:(u,g,o)其中必须每一位都包含对应位的权限
举例:
find -perm 755 #对应权限位必须为755全满足 find -perm /222 #3个权限位任意人权限位有写权限就满足 find -perm -222 #3个权限位中都必须都包含有写权限就满足 find -perm -002 #3个权限位只有其它用户必须包含写权限
ACTION(动作处理):
-print:默认显示文件集合路径
-ls:对于匹配的文件进行类似ls -l的长模式格式显示
-delete:删除查找到的文件
-fls file:查找到的所有文件的长格式信息保存的指定文件中,类似重定向输出
-ok COMMAND {} \; 对查找到的每个文件执行指定的命令操作
每个文件被执行命令之前都会进行交互式判断
-exec COMMAND {} \; 对查找到的每个文件执行COMMAND指定的命令,无需判断
{} : 表示查询到的每个文件自身路径引用
find 传递的文件到指定命令时,查询的所有文件成一个集合保存为{},命 令调用的时文件的集合
注意:COMMAND参数如果指定过多,可能会不支持,这时需要借助 xargs 命令,例如:
find ./ -user u1 | xargs chmod -o-x {} \;
注意:最后引用完一定要加上 \; ,否则会报错
#查询/etc 下所有后缀名为.conf的配置文件并拷贝到/backup目录下且后缀为.bak find /etc -name “*.conf” exec cp {} /backup/{}.bak \; #提示/tmp 下属主为u1用户且访问时间超过3天的文件,并删除 find /etc -user u1 -atime +3 -ok rm {} \; #查询当前用户家目录下可被其它用户写入的文件,并去掉其它用户的执行权限 find ~ -perm /002 -exec chmod o-x {} \; #查询/test 下权限为664且后缀为.sh普通文件,修改权限位为755 find /test -perm 664 -name “*.sh” -exec chmod 755 {} \; #列出/home下所有的目录 find /home -type d -ls
练习
1、查找/var目录下属主为root,且属组为mail的所有文件
[[email protected] ~]# find /var -user root -group mail -ls 394264 4 drwxrwxr-x 2 root mail 4096 Aug 12 19:50 /var/spool/mail
2、查找/var目录下不属于root、lp、gdm的所有文件
方法(1)
[[email protected] ~]# find /var -not -user root -not -user lp -not -user gdm -ls | head -n 3 394419 4 drwxr-xr-x 2 ntp ntp 4096 May 12 04:04 /var/log/ntpstats 394435 4 drwx------ 2 postfix root 4096 Jul 20 17:13 /var/lib/postfix 395601 4 -rw------- 1 postfix postfix 33 Aug 11 09:34 /var/lib/postfix/master.lock
方法(2)
[[email protected] ~]# find /var -not \( -user root -o -user lp -o -user gdm \) -ls | head -n 3 394419 4 drwxr-xr-x 2 ntp ntp 4096 May 12 04:04 /var/log/ntpstats 394435 4 drwx------ 2 postfix root 4096 Jul 20 17:13 /var/lib/postfix 395601 4 -rw------- 1 postfix postfix 33 Aug 11 09:34 /var/lib/postfix/master.lock
3、查找/var目录下最近一周内其内容修改过,同时属主不为root,也不是postfix的文件
[[email protected] ~]# find /var -mtime -7 -not -user root -not -user postfix -ls 395707 4 -rw-r--r-- 1 gdm gdm 934 Aug 11 08:38 /var/log/gdm/:0-greeter.log 394459 4 drwxrwx--T 9 gdm gdm 4096 Aug 11 08:38 /var/lib/gdm 395667 4 -rw-r--r-- 1 gdm gdm 463 Aug 11 08:38 /var/lib/gdm/.dbus/session-bus/3c89f7c587667a8ae6dd8fd50000000e-0 395670 4 -rw------- 1 gdm gdm 620 Aug 11 08:38 /var/lib/gdm/.ICEauthority 395671 4 drwx------ 2 gdm gdm 4096 Aug 11 08:38 /var/lib/gdm/.gconfd 395688 36 -rwx------ 1 gdm gdm 32963 Aug 11 08:38 /var/lib/gdm/.gconfd/sav [[email protected] ~]# find /var -mtime -7 -not \( -user root -o -user postfix \) -ls 395707 4 -rw-r--r-- 1 gdm gdm 934 Aug 11 08:38 /var/log/gdm/:0-greeter.log 394459 4 drwxrwx--T 9 gdm gdm 4096 Aug 11 08:38 /var/lib/gdm 395667 4 -rw-r--r-- 1 gdm gdm 463 Aug 11 08:38 /var/lib/gdm/.dbus/session-bus/3c89f7c587667a8ae6dd8fd50000000e-0 395670 4 -rw------- 1 gdm gdm 620 Aug 11 08:38 /var/lib/gdm/.ICEauthority 395671 4 drwx------ 2 gdm gdm 4096 Aug 11 08:38 /var/lib/gdm/.gconfd
4、查找当前系统上没有属主或属组,且最近一个周内曾被访问过的文件
[[email protected] ~]# find / \( -nouser -nogroup \) -mtime -7 find: `/proc/33812/task/33812/fd/5‘: No such file or directory find: `/proc/33812/task/33812/fdinfo/5‘: No such file or directory find: `/proc/33812/fd/5‘: No such file or directory find: `/proc/33812/fdinfo/5‘: No such file or directory
6、查找/test目录下所有用户都没有写权限的文件
[[email protected] test3]# ls -l total 12 -rwxr-xr-x 1 root root 0 Aug 15 08:10 aa -rwxr--r-- 1 root root 0 Aug 15 08:10 bb -r--r-xr-- 1 root root 0 Aug 15 08:10 cc [[email protected] test3]# find ./ -not -perm /222 -ls 1738953 4 -r--r-xr-- 1 root root 0 Aug 15 08:10 ./cc
7、查找/test目录下至少有一类用户没有执行权限的文件
[[email protected] test3]# ls -l total 12 -rwxr-xr-x 1 root root 0 Aug 15 08:10 aa -rwxr--r-- 1 root root 0 Aug 15 08:10 bb -r--r-xr-- 1 root root 0 Aug 15 08:10 cc [[email protected] test3]# find ./ -not -perm -111 -ls 1738952 4 -rwxr--r-- 1 root root 0 Aug 15 08:10 ./bb 1738953 4 -r--r-xr-- 1 root root 0 Aug 15 08:10 ./cc
8、查找/etc/init.d目录下,所有用户都有执行权限,且其它用户有写权限的文件
[[email protected] test3]# find /etc/init.d/ -perm -112 -ls 2459601 4 -rwxr-xrwx 1 root root 0 Aug 15 06:34 /etc/init.d/aa
9、/etc目录下至少有一类有写权限
[[email protected] test3]# find /etc -perm /222 -ls | wc -l
2187
[[email protected] test3]# find /etc -perm /222 -ls | head -n 5
2457601 16 drwxr-xr-x 101 root root 12288 Aug 15 08:51 /etc
2457680 0 lrwxrwxrwx 1 root root 10 Aug 2 10:43 /etc/rc6.d -> rc.d/rc6.d
2458137 8 -rw-r--r-- 1 root root 1112 Jul 26 2006 /etc/minicom.users
2458851 8 drwxr-xr-x 2 root root 4096 Aug 2 10:44 /etc/setuptool.d
2458853 8 -rw-r--r-- 1 root root 69 Dec 1 2006 /etc/setuptool.d/98system-config-authentication
10、查找当前系统上没有属主或属组且最近1天内曾被访问过的文件,并将其属主属组均修改为root;
[[email protected] test3]# find / \( -nouser -o -nogroup \) -atime -1 -exec chown root {} \;
11、查找/etc目录下大于1M的文件,并将其文件名写入/tmp/etc.largefiles文件中;
[[email protected] test3]# find /etc -size +1M -exec echo {} >> /tmp/etc.largefiles {} \; [[email protected]calhost test3]# cat /tmp/etc.largefiles /etc/selinux/targeted/modules/active/base.linked /etc/selinux/targeted/modules/active/base.linked /etc/selinux/targeted/modules/active/base.pp /etc/selinux/targeted/modules/active/base.pp /etc/selinux/targeted/modules/active/policy.kern /etc/selinux/targeted/modules/active/policy.kern /etc/selinux/targeted/policy/policy.21 /etc/selinux/targeted/policy/policy.21 /etc/gconf/schemas/gnome-terminal.schemas /etc/gconf/schemas/gnome-terminal.schemas /etc/gconf/schemas/apps_nautilus_preferences.schemas /etc/gconf/schemas/apps_nautilus_preferences.schemas /etc/gconf/schemas/gok.schemas /etc/gconf/schemas/gok.schemas /etc/gconf/schemas/metacity.schemas /etc/gconf/schemas/metacity.schemas /etc/gconf/gconf.xml.defaults/%gconf-tree.xml /etc/gconf/gconf.xml.defaults/%gconf-tree.xml