查找文件
约 1371 个字 129 行代码 1 张图片 预计阅读时间 6 分钟
通配符
通配符不是正则表达式,可直接用于 Linux 中一些系统命令。
常用的通配符:
*
:0 到多个字符
?
:一个字符
[字符集]
:字符集里的任一字符
[a-b]
:按字符顺序,字符 a
到字符 b
之间(含两端)的任一字符
[^字符集]
:上两个的取反关系,即不属于字符集里面的内容的字符
使用通配符时,不能用引号包裹。
查找文件的几种方式
which
:寻找可执行文件
whereis
:寻找特定文件
locate
:搜索文件(按关键字)
find
:多样化高级查找
which
- 寻找可执行文件
只在 PATH
下查找
常用选项:
例:
# Ubuntu 20.04 LTS
ding@ding-server:~$ which vim
/usr/bin/vim
ding@ding-server:~$ which pwd
/usr/bin/pwd
ding@ding-server:~$ which which
/usr/bin/which
ding@ding-server:~$ which -a echo
/usr/bin/echo
/bin/echo
ding@ding-server:~$ which cd
ding@ding-server:~$
# CentOS Linux release 7.9.2009
ding@ding-server:~$ which vim
/usr/bin/vim
ding@ding-server:~$ which pwd
/usr/bin/pwd
ding@ding-server:~$ which which
alias which = 'alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
/usr/bin/alias
/usr/bin/which
ding@ding-server:~$ which -a echo
/usr/bin/echo
ding@ding-server:~$ which cd
ding@ding-server:~$
whereis
- 寻找特定文件
在 PATH
和 MANPATH
中查找。
选项:
-b
:只查找二进制文件
-m
:只查找 manual
路径下的文件
-s
:只查找 source
源文件
-u
:查找其他文件
-l
:列出上述条件的查找范围
例:
ding@ding-server:~$ whereis passwd
passwd: /usr/bin/passwd /etc/passwd /usr/share/man/man5/passwd.5.gz /usr/share/man/man1/passwd.1ssl.gz /usr/share/man/man1/passwd.1.gz
ding@ding-server:~$ whereis -b passwd
passwd: /usr/bin/passwd /etc/passwd
ding@ding-server:~$ whereis -m passwd
passwd: /usr/share/man/man5/passwd.5.gz /usr/share/man/man1/passwd.1ssl.gz /usr/share/man/man1/passwd.1.gz
ding@ding-server:~$ whereis -s passwd
passwd:
ding@ding-server:~$ whereis -u passwd
passwd: /usr/bin/passwd /etc/passwd /usr/share/man/man5/passwd.5.gz /usr/share/man/man1/passwd.1ssl.gz /usr/share/man/man1/passwd.1.gz
locate
- 搜索文件(按关键字)
Ubuntu 下要安装:
基于索引文件查找,故速度较快。
一般每天更新一次索引,如果有新文件可能查不到。强制更新索引:
选项:
-i
:忽略大小写
-c
:仅显示文件数量
-l 数字
:仅显示特定条数
-r
:使用基础正则表达式
--regex
:使用扩展正则表达式
-S
:输出索引文件信息(后面不添加文件名的一部分)
例:
ding@ding-server:~$ locate -l 5 vim
/etc/vimrc
/etc/libreport/events.d/vimrc_event.conf
/etc/profile.d/vim.csh
/etc/profile.d/vim.sh
/home/foxconn/.vim
ding@ding-server:~$ locate -S
Database /var/lib/mlocate/mlocate.db:
114 ,213 directories
839 ,650 files
92 ,832,925 bytes in file names
27 ,867,065 bytes used to store database
ding@ding-server:~$ locate -l 100 -r 'l[a-z]ng\.sh' # 查找名称含有 l*ng.sh 的文件, 其中 * 表示一个小写字母
/etc/profile.d/lang.sh
/usr/lib/rpm/find-lang.sh
ding@ding-server:~$ locate -l 100 --regex 'l[a-z]+ng\.sh' # 查找名称含有 l*ng.sh 的文件, 其中 * 表示至少一个小写字母
/etc/profile.d/lang.sh
/home/foxconn/python3/Python-3.9.5/Doc/library/multiprocessing.shared_memory.rst
/usr/lib/rpm/find-lang.sh
find
- 多样化高级查找
遍历目录查找,速度较慢,但能够查到新文件。
如果访问时出错会报错,影响观感,可将其重定向掉。
路径为要查找的文件所在的路径,多个路径用空格隔开。
与时间相关的选项
以下 n
均为数字,mtime
的情况也可以用在 atime
、ctime
上,time
可以换为 min
表分钟。
-mtime n
:在“n
天之前的一天之内”被修改过内容的文件
-mtime +n
:在“n
天之前(不含 n
天本身)”被修改过内容的文件
-mtime -n
:在“n
天之内(含 n
天本身)”被修改过内容的文件
-newer 文件
:列出比给定文件新的文件
与时间相关的选项图解
与用户、用户组相关的选项
-uid UID
:文件所有者 UID 为给定值
-gid GID
:文件用户组 GID 为给定值
-user 用户名
:文件所有者为给定用户
-group 组名
:文件用户组为给定用户组
-nouser
:文件所有者不在 /etc/passwd
中
-nogroup
:文件用户组不在 /etc/group
中
-nouser
或 -nogroup
出现的情况:
对应用户、用户组被删除
文件来源为其他地方,且保留了属性
与文件相关的选项
b
c
d
p
f
l
s
块设备
字符设备
目录
管道
普通文件
符号链接
套接字
与权限相关的选项
以下数字包含三位和四位的情况。
-perm 数字
:权限为给定数字
-perm -数字
:权限包含给定数字
-perm /数字
:权限包含给定数字中的任意权限
逻辑运算符
额外可进行的操作
-exec 命令
:执行命令,通常的格式如下:
find [ 路径] [ 选项] -exec ls -l {} \;
每个文件执行一次命令,用 {}
表示查到的文件的路径
最后要有分号并转义
-ok 命令
:同上,但执行前要输入 y
才执行
-print
:将结果打印在屏幕上(默认)
例
列出全部含有 SUID 属性的普通文件,并打印它们的详细文件信息。
ding@ding-server:~$ find / -perm /4000 -type f 2 > /dev/null -exec ls -l {} \;
-r-Sr--r-- 1 root docker 16696 May 23 14 :43 /home/foxconn/p/test
-rwsr-xr-x 1 root root 22840 Feb 21 20 :58 /usr/lib/policykit-1/polkit-agent-helper-1
-rwsr-xr-x 1 root root 473576 Mar 30 21 :03 /usr/lib/openssh/ssh-keysign
-rwsr-xr-x 1 root root 14488 Jul 8 2019 /usr/lib/eject/dmcrypt-get-device
-rwsr-xr-- 1 root messagebus 51344 Apr 29 20 :03 /usr/lib/dbus-1.0/dbus-daemon-launch-helper
-rwsr-xr-x 1 root root 53040 Mar 14 16 :26 /usr/bin/chsh
-rwsr-xr-x 1 root root 67816 Feb 7 21 :33 /usr/bin/su
-rwsr-xr-x 1 root root 85064 Mar 14 16 :26 /usr/bin/chfn
-rwsr-xr-x 1 root root 88464 Mar 14 16 :26 /usr/bin/gpasswd
-rwsr-xr-x 1 root root 166056 Jan 19 2021 /usr/bin/sudo
-rwsr-sr-x 1 daemon daemon 55560 Nov 13 2018 /usr/bin/at
-rwsr-xr-x 1 root root 31032 Feb 21 20 :58 /usr/bin/pkexec
-rwsr-xr-x 1 root root 39144 Mar 7 2020 /usr/bin/fusermount
-rwsr-xr-x 1 root root 68208 Mar 14 16 :26 /usr/bin/passwd
-rwsr-xr-x 1 root root 55528 Feb 7 21 :33 /usr/bin/mount
-rwsr-xr-x 1 root root 39144 Feb 7 21 :33 /usr/bin/umount
-rwsr-xr-x 1 root root 44784 Mar 14 16 :26 /usr/bin/newgrp
练习
1
查找家目录下的所有扩展名为 sh
的文件,并统计它们的第一行书写形式的数量(只统计第一行以 #!
开头的)。
参考答案
ding@ding-server:~$ find ~ -name '*.sh' 2 > /dev/null -exec head -1 {} \; \
> | grep '^#!' | sort | uniq -c
22 #!/bin/bash
22 #!/bin/sh
9 #!/usr/bin/env bash
如果考虑家目录下面有自己访问不了的文件:
ding@ding-server:~$ cd ~; sudo find ./ -name '*.sh' -exec head -1 {} \; \
> | grep '^#!' | sort | uniq -c
23 #!/bin/bash
22 #!/bin/sh
9 #!/usr/bin/env bash
!!! info
在 `cd ~; sudo find ./` 处,我尝试过传入用户名,前面加上 `~`,但不行;故先用自己进入家目录,后面 `find` 用 `./`
其他方法(来自一位同事,稍加修改)
ding@ding-server:~$ cd ~; sudo find ./ -type f -name *.sh -exec head -n 1 {} \; | grep -E "^#!" \
> | awk '{S[$1]++} END {for (a in S) {print a, S[a]}}'
#!/bin/sh 22
#!/bin/bash 23
#!/usr/bin/env 9
上述过程中数据的变化:
// 假如 grep -E "^#!" 之后
# ! /bin/bash
# ! /usr/bin/env bash
# ! /bin/sh
# ! /usr/bin/env bash
# ! /bin/bash
// awk '{S[$1]++}' 的实质
S [ # ! /bin/bash] ++
S [ # ! /usr/bin/env bash] ++
S [ # ! /bin/sh] ++
S [ # ! /usr/bin/env bash] ++
S [ # ! /bin/bash] ++
// awk '{S[$1]++}' 之后
S [ # ! /bin/bash] == 1
S [ # ! /usr/bin/env bash] == 1
S [ # ! /bin/sh] == 1
S [ # ! /usr/bin/env bash] == 2
S [ # ! /bin/bash] == 2
2
查找 /usr/bin
下的符号链接文件,并列出它们的源文件的详细信息。
不需要再找链接的链接。记得去重。
提示:ls -d 目录
:对目录,只显示目录的信息,而非目录下的文件的信息。
参考答案
这种操作最好先分步执行,查看输出结果,根据结果设计下一步;最后组合。
ding@ding-server:~$ cd /usr/bin; sudo find /usr/bin -type l -exec ls -l {} \; \
> | awk '{print $NF}' | sort -u | xargs -n 1 ls -ld
drwxr-xr-x 2 root root 36864 May 25 16 :18 .
-rwxr-xr-x 1 root root 7415 Oct 26 2021 add-apt-repository
-rwxr-xr-x 1 root root 2558 Dec 5 2019 apport-bug
-rwsr-sr-x 1 daemon daemon 55560 Nov 13 2018 at
-rwxr-xr-x 1 root root 1183448 Apr 18 17 :14 bash
-rwxr-xr-x 1 root root 819296 Feb 15 2020 btrfs
-rwxr-xr-x 1 root root 2172376 Nov 25 2021 busybox
-rwxr-xr-x 1 root root 8363 Feb 17 2020 byobu
-rwxr-xr-x 1 root root 389 Dec 17 2019 chardetect3
-rwxr-xr-x 1 root root 963 Feb 17 2020 col1
lrwxrwxrwx 1 root root 22 Mar 10 01 :57 cpp-9 -> x86_64-linux-gnu-cpp-9
-rwxr-xr-x 1 root root 129816 Jul 19 2019 dash
...
!!! info
在 `cd /usr/bin;` 处:经测试可以发现,链接指向的很多都是相对路径,考虑到最后面的 `ls`,故先进入该目录
总结
解决问题的方式不止一种,不过最好能够找到最佳的方式。
参考资料