在 Linux 中使用 find 和 grep 查找文件和内容

一、find

1. 通过名称搜索

1
2
3
4
5
6
7
8
9
# 大小写敏感
$ find -name "query"
# 大小写不敏感
$ find -iname "query"
# 反选
$ find -not -name "query_to_avoid"
$ find \! -name "query_to_avoid"
# 通配符
$ find -name "*query*"

2. 通过类型搜索

  • f: regular file
  • d: directory
  • l: symbolic link
  • c: character devices
  • b: block devices
1
2
3
4
5
6
# 类型为字符设备
$ find /dev -type c
# 类型为文件,且以.conf结尾
$ find /usr -type f -name "*.conf"
# 类型为文件,或以.conf结尾
$ find /usr -type f -or -name "*.conf"

3. 通过时间或大小搜索

  • c: bytes
  • k: kilobytes
  • M: megabytes
  • G: gigabytes
  • b: 512-byte blocks
1
2
3
4
5
6
# 等于50bytes
$ find /usr -size 50c
# 小于50bytes
$ find /usr -size -50c
# 大于700M
$ find /usr -size +700M
  • Access Time (-atime): The last time a file was read or written to.
  • Modification Time (-mtime): The last time the contents of the file were modified.
  • Change Time (-ctime): The last time the file’s inode metadata was changed.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ date
Sun May 14 11:05:59 CST 2023

# 最近1天修改
$ find /usr -mtime 1
drwxr-xr-x. 2 root root 4096 May 13 10:49 LC_MESSAGES
# 不到1天前修改
$ find /usr -mtime -1
drwxr-xr-x. 2 root root 17 May 13 11:50 epel-release-7
# 上次更改时间超过3天
$ find /usr -ctime +3
# 最近1分钟修改
$ find /usr -mmin -1
# 返回比参考文件更晚创建或更改的
$ ll
drwxr-xr-x. 2 root root 6 May 14 11:13 111
-rw-r--r--. 1 root root 0 May 14 11:13 222.txt
drwxr-xr-x. 2 root root 6 May 14 11:14 333
-rw-r--r--. 1 root root 0 May 14 11:14 444.txt
$ find . -newer 333
.
./444.txt

4. 通过所有者和权限搜索

1
2
3
4
5
6
7
8
9
# 属主是syslog
$ find /var -user syslog
# 属组是shadow
$ find /etc -group shadow
# 权限为644
$ find / -perm 644
# 权限至少644
$ find / -perm -644
drwxr-xr-x. 2 root root 6 Apr 11 2018 man2x

5. 按深度过滤

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
$ mkdir -p /tmp/test/level1dir{1..10}/level2dir{1..10}/level3dir{1..10}
$ touch /tmp/test/{file{1..10},level1dir{1..10}/{file{1..10},level2dir{1..10}/{file{1..10},level3dir{1..10}/file{1..10}}}}
$ cd /tmp/test
# 最大深度2层
$ find -maxdepth 2 -name file1
./level1dir1/file1
./level1dir2/file1
./level1dir3/file1
./level1dir4/file1
./level1dir5/file1
./level1dir6/file1
./level1dir7/file1
./level1dir8/file1
./level1dir9/file1
./level1dir10/file1
./file1
# 最大深度2层,且最小深度2层
$ find -mindepth 2 -maxdepth 2 -name file1
./level1dir1/file1
./level1dir2/file1
./level1dir3/file1
./level1dir4/file1
./level1dir5/file1
./level1dir6/file1
./level1dir7/file1
./level1dir8/file1
./level1dir9/file1
./level1dir10/file1

6. 对 find 结果执行命令

1
2
# `{}`用作查找匹配的文件的占位符;`\`让find知道命令在哪里结束
$ find . -type f -perm 644 -exec chmod 664 {} \;

二、grep

  • grep 命令用于查找文本文件中的正则表达式或字符串
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# 基本使用
$ grep "halt" /etc/passwd
halt:x:7:0:halt:/sbin:/sbin/halt
# 结果着色
$ grep --color "halt" /etc/passwd
# 忽略大小写
$ grep -i "halt" /etc/passwd
# 匹配结果的行数
$ grep -c "halt" /etc/passwd
# 反选
$ grep -v "halt" /etc/passwd
# 输出匹配文本所在行号
$ grep -n "halt" /etc/passwd
# 匹配“单词”
$ grep -w "halt" /etc/passwd
# 文件夹中搜索
$ grep -r "halt" /etc/
/etc/aliases:halt: root
/etc/passwd-:halt:x:7:0:halt:/sbin:/sbin/halt
/etc/shadow-:halt:*:18353:0:99999:7:::
/etc/passwd:halt:x:7:0:halt:/sbin:/sbin/halt
# 只显示文件名
$ grep -lr "halt" /etc/

# 正则表达式
# ^ Matches characters at the beginning of a line
# $ Matches characters at the end of a line
# "." Matches any character
# [a-z] Matches any characters between A and Z
# [^ ..] Matches anything apart from what is contained in the brackets

# 以`#`开头
$ grep ^# 1.txt
# 以`.`结尾
$ grep \\.$ 1.txt

# 结合管道符
$ ip a | grep ens
# -A: after; -B: before
$ ip a | grep -A 2 -B 2 ens

# 文件类型是txt,内容有"Hello"
$ find / -type f -name "*.txt" | xargs grep "Hello"

参考