2023-05-31    2024-02-26    2151 字  5 分钟

文件查找常用场景:

  • 忘记文件所在的具体位置,根据文件名模糊查询。
  • 查找N天前的日志并删除,释放磁盘空间。

find命令可以根据不同的条件来进行查找文件。我们可以根据文件名称、文件大小、文件修改时间、属主属组、权限等方式查找相应的文件。

find基本用法

find命令的基本语法:

命令 路径 选项 表达式 动作
find [path] [options] [expression] [action]
查找 地区 美食 火锅 下单

按文件名称查找

1
2
3
[root@localhost ~]# touch ifcfg-eth0
[root@localhost ~]# touch IFCFG-ETH0
[root@localhost ~]# mkdir ifcfg

在当前目录下查找名称以ifcfg开头的文件。

1
[root@localhost ~]# find ./ -name "ifcfg*"

在当前目录下查找名称以iFC开头的文件,不区分大小写。

1
[root@localhost ~]# find /etc/ -iname "iFC*"

按文件类型查找

查找文件,f表示文件类型。

1
[root@localhost ~]# find /dev/ -type f

查找目录,d表示目录类型。

1
[root@localhost ~]# find /dev/ -type d

查找链接文件,l表示链接类型。

1
[root@localhost ~]# find /dev/ -type l

查找块设备,b表示块设备类型。

1
[root@localhost ~]# find /dev/ -type b

查找字符设备,c表示字符设备类型。

1
[root@localhost ~]# find /dev/ -type c

查找套接字,s表示套接类型。

1
[root@localhost ~]# find /dev/ -type s

按文件大小查找

/etc下查找大于5M的文件。

1
[root@localhost ~]# find /etc/ -size +5M

/etc下查找小于5M的文件。

1
[root@localhost ~]# find /etc/ -size -5M

/etc下查找大小为5M的文件(四舍五入)。

1
[root@localhost ~]# find /etc/ -size 5M

按修改时间查找

如图,假设当前日期是31号,向前推7天(不包括当前日期)为24号,24号以前的日期用+7表示,24号之后的日期用-7表示,24号当天用7表示。

时间轴

创建文件并修改当前时间。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
[root@localhost ~]# date
Tue Jan  9 08:13:52 CST 2024
# 系统当前日期为31号
[root@localhost ~]# for i in {1..31}; do date -s "2024/01/$i" ; touch file-$i ; done
# 通过循环创建file-1  , file-31
[root@localhost ~]# ls
file-1   file-14  file-19  file-23  file-28  file-4  file-9
file-10  file-15  file-2   file-24  file-29  file-5
file-11  file-16  file-20  file-25  file-3   file-6
file-12  file-17  file-21  file-26  file-30  file-7
file-13  file-18  file-22  file-27  file-31  file-8
[root@localhost ~]# date
Wed Jan 31 00:03:37 CST 2024

查找第7天的文件。

1
2
3
# -mtime 7表示从当前日期向前推7天,即31-7=24.
[root@localhost ~]# find ./ -type f -mtime 7
./file-24

筛选出7天之前的文件。

1
2
3
4
[root@localhost ~]# find ./ -type f -mtime +7 -name "file*"| xargs ls
./file-1   ./file-12  ./file-15  ./file-18  ./file-20  ./file-23  ./file-5  ./file-8
./file-10  ./file-13  ./file-16  ./file-19  ./file-21  ./file-3   ./file-6  ./file-9
./file-11  ./file-14  ./file-17  ./file-2   ./file-22  ./file-4   ./file-7

筛选出最近7天的文件。

1
2
[root@localhost ~]# find ./ -type f -mtime -7 -name "file*"| xargs ls
./file-25  ./file-26  ./file-27  ./file-28  ./file-29  ./file-30  ./file-31

保留最近7天的文件。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
[root@localhost ~]# find ./ -name "file*" -type f -mtime +7 | xargs rm -f
[root@localhost ~]# ll
total 0
-rw-r--r--. 1 root root    0 Jan 24 00:00 file-24
-rw-r--r--. 1 root root    0 Jan 25 00:00 file-25
-rw-r--r--. 1 root root    0 Jan 26 00:00 file-26
-rw-r--r--. 1 root root    0 Jan 27 00:00 file-27
-rw-r--r--. 1 root root    0 Jan 28 00:00 file-28
-rw-r--r--. 1 root root    0 Jan 29 00:00 file-29
-rw-r--r--. 1 root root    0 Jan 30 00:00 file-30
-rw-r--r--. 1 root root    0 Jan 31 00:00 file-31

按用户和组查找

查找属主是snoopy的文件。

1
[root@localhost ~]# find /home/ -user snoopy

查找属组是snoopy的文件。

1
[root@localhost ~]# find /home/ -group snoopy

查找属主是snoopy,属组也是snoopy的目录。

1
[root@localhost ~]# find /home/ -type d -user snoopy -group snoopy

查找没有属主的文件。

1
[root@localhost ~]# find /home/ -nouser

查找没有属组的文件。

1
[root@localhost ~]# find /home/ -nogroup

查找没有属主和属组的文件。

1
[root@localhost ~]# find / -nouser -nogroup

查找文件内容

记得文件的内容是什么,但是不清楚文件名称是什么,也不知道路径在哪,怎么办?

1
[root@localhost ~]# find /etc/ -type f | xargs grep "systemd-network" --color=auto

通过grep也可以实现。

1
[root@localhost ~]# grep -r "systemd-network" /etc/*

逻辑运算

符号 作用
-a
-o
非,同-not

查找/home目录下,属主不是root的所有文件。

1
[root@localhost ~]# find /home ! -user root -type f | xargs ls -l

查找/home目录下,属主属于snoopy,并且大小大于1k的文件。

1
2
3
[root@localhost ~]# find /home -user snoopy -size +1k -type f | xargs ls -lh
-rw-rw-r--. 1 snoopy snoopy 2.5K Aug  8 10:35 /home/snoopy/a
-rw-rw-r--. 1 snoopy snoopy 3.2K Aug  8 10:40 /home/snoopy/c

处理动作

查找到一个文件后,需要对文件进行如何处理。

动作 含义
-print 打印查找到的内容。
-ls 以长格式方式显示查找到的内容。
-delete 删除查找到的文件,仅能删除文件和空目录。
-exec 自定义shell命令。

当我们想查找/var/log/目录下7天以前的日志文件并删除,可通过以下方式实现:

方式一:

1
[root@localhost ~]# find /var/log/ -type f -name "*.log" -mtime +7 | xargs rm -f

方式二:

1
[root@localhost ~]# find /var/log/ -type f -name "*.log" -mtime +7 -exec rm -rf {} \;

方式三:

1
[root@localhost ~]# find /var/log/ -type f -name "*.log" -mtime +7 -delete

以上三种方式首选通过xargs连接处理动作,此方式处理速度最快,会批量把文件传给处理命令。

次选exec连接处理动作,此方式处理速度次之,会把逐个文件传给处理命令。

不推荐使用delete删除文件,此方式仅能删除文件和空目录。

练习

  1. 查找/var目录下,属主不是root,且文件名不以f开头的文件。

    1
    
    [root@localhost ~]# find /var ! -user root ! -name "f*" -type f
    
  2. 查找/var目录下属主为root,且属组为mail的所有文件。

    1
    
    [root@localhost ~]# find /var -user root -group mail -type f
    
  3. 查找/var目录下不属于rootlp的所有文件。

    1
    
    [root@localhost ~]# find /var/ ! -user root ! -user lp -type f
    
  4. 查找/var目录下最近一周内其内容修改过,同时属主不为root,也不是postfix的文件。

    1
    
    [root@localhost ~]# find /var/ -mtime -7 ! -user root ! -user postfix -type f
    
  5. 查找/etc目录下大于1M且类型为普通文件的所有文件。

    1
    
    [root@localhost ~]# find /etc/ -type f -size +1M
    
  6. /etc/中的所有目录(仅目录)复制到/tmp下,目录结构不变。

    1
    2
    3
    4
    
    [root@localhost ~]# find /etc/ -type d | xargs -i mkdir -p /tmp/{}
    # -i 表示 find 传递给xargs的结果 由{}来代替
    或者
    [root@localhost ~]# find /etc/ -type d -exec mkdir -p /tmp/{} \;
    
  7. /etc目录复制到/var/tmp/目录下,并查找/var/tmp/etc中的所有权限为777的目录和权限666的文件。

    1
    2
    3
    4
    5
    6
    
    [root@localhost ~]# cp /etc/ /var/tmp/ -rp
    [root@localhost ~]# find /var/tmp/etc/ -type d | xargs -i chmod 777 {}
    [root@localhost ~]# find /var/tmp/etc/ -type f | xargs -i chmod 666 {}
    [root@localhost ~]# find /var/tmp/etc/ -type d -exec chmod 777 {} \;
    [root@localhost ~]# find /var/tmp/etc/ -type f -exec chmod 666 {} \;
    
  8. 保留/var/log/下最近7天的日志文件,其他全部删除。

    1
    
    [root@localhost ~]# find /var/log/ -mtime +7 -type f | xargs rm -rf
    
  9. 创建touch file{1..10}10个文件, 保留file9,其他一次全部删除。

    1
    
    [root@localhost ~]# find ./ ! -name "file9" -name "file*" | xargs rm -rf
    
  10. 解释如下每条命令含义。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    mkdir /root/dir1
    touch /root/dir1/file{1..10}
    find /root/dir1 -type f -name "file5"
    find /root/dir1 ! -name "file5"
    find /root/dir1 -name "file5" -o -name "file9"
    find /root/dir1 -name "file5" -o -name "file9" -ls
    find /root/dir1 \( -name "file5" -o -name "file9" \) -ls
    find /root/dir1 \( -name "file5" -o -name "file9" \) -exec rm -rvf {} \;
    find /root/dir1  ! \( -name "file4" -o -name "file8" \) -exec rm -vf {}  \; 
    

image-20231028232834657