grep 命令:从文本中精准筛选信息的实用指南
文章目录
- [grep 命令:从文本中精准筛选信息的实用指南](#grep 命令:从文本中精准筛选信息的实用指南)
-
- [一、什么是 grep?为什么要用它?](#一、什么是 grep?为什么要用它?)
- [二、grep 基本语法](#二、grep 基本语法)
- 三、常用选项详解(附实例)
-
- [(一)模式选择:怎么定义 "要找的内容"?](#(一)模式选择:怎么定义 “要找的内容”?)
-
- [1. `-E`:支持复杂的匹配规则(扩展正则表达式)](#1.
-E
:支持复杂的匹配规则(扩展正则表达式)) - [2. `-e`:一次匹配多个模式](#2.
-e
:一次匹配多个模式) - [3. `-f`:从文件中读取匹配模式](#3.
-f
:从文件中读取匹配模式) - [4. `-i`:忽略大小写](#4.
-i
:忽略大小写) - [5. `-w`:只匹配完整单词](#5.
-w
:只匹配完整单词) - [6. `-x`:只匹配完整的行](#6.
-x
:只匹配完整的行)
- [1. `-E`:支持复杂的匹配规则(扩展正则表达式)](#1.
- (二)输出控制:怎么展示筛选结果?
-
- [1. `-v`:反向匹配(显示不包含模式的行)](#1.
-v
:反向匹配(显示不包含模式的行)) - [2. `-m`:限制最大匹配数量](#2.
-m
:限制最大匹配数量) - [3. `-c`:统计匹配到的行数](#3.
-c
:统计匹配到的行数) - [4. `-n`:显示匹配行的行号](#4.
-n
:显示匹配行的行号) - [5. `-o`:只显示匹配到的部分(不显示整行)](#5.
-o
:只显示匹配到的部分(不显示整行)) - [6. `-q`:静默模式(只判断是否存在,不输出内容)](#6.
-q
:静默模式(只判断是否存在,不输出内容))
- [1. `-v`:反向匹配(显示不包含模式的行)](#1.
- (三)查找文件:如何在目录中递归搜索?
-
- [1. `-r` / `-R`:递归搜索目录](#1.
-r
/-R
:递归搜索目录) - [2. `-h` / `-H`:控制是否显示文件名](#2.
-h
/-H
:控制是否显示文件名) - [3. `-l` / `-L`:只显示包含 / 不包含模式的文件名](#3.
-l
/-L
:只显示包含 / 不包含模式的文件名)
- [1. `-r` / `-R`:递归搜索目录](#1.
- (四)上下文控制:显示匹配行的前后内容
-
- [1. `-B`:显示匹配行和前面的行](#1.
-B
:显示匹配行和前面的行) - [2. `-A`:显示匹配行和后面的行](#2.
-A
:显示匹配行和后面的行) - [3. `-C`:显示匹配行和前后的行](#3.
-C
:显示匹配行和前后的行)
- [1. `-B`:显示匹配行和前面的行](#1.
- 四、总结
一、什么是 grep?为什么要用它?
在 Linux 系统中,我们经常需要从大量文本中快速找到包含特定内容的行 ------ 比如从日志文件中找错误信息、从配置文件中找关键参数。grep
就是专门干这件事的工具,它能像 "文本侦探" 一样,从文件或命令输出中精准筛选出符合条件的内容。
Linux 处理文本有 "三剑客":grep
擅长 "筛选",sed
擅长 "修改",awk
擅长 "格式化输出"。掌握 grep
,能让你在处理文本时效率翻倍。
二、grep 基本语法
grep
的使用场景主要有两种,语法对应如下:
-
从命令输出中筛选 (通过管道
|
传递数据):bash其他命令 | grep [选项] 匹配模式
例:
[bq@shell bin]$ ls -l | grep 'txt'
(从ls
输出中找包含txt
的行) -
从文件中筛选:
bashgrep [选项] 匹配模式 文件名
例:
[bq@shell bin]$ grep 'error' app.log
(从app.log
中找包含error
的行)
三、常用选项详解(附实例)
(一)模式选择:怎么定义 "要找的内容"?
这部分选项用来控制 "匹配规则",让 grep
知道你想找什么样的内容。
1. -E
:支持复杂的匹配规则(扩展正则表达式)
理论 :默认情况下,grep
只支持简单的正则表达式(比如 *
?
),加上 -E
后可以用更复杂的规则(比如 {n}
表示重复次数、|
表示 "或"),相当于 egrep
命令。
示例 :找连续出现 3 次 dog
的行
bash
# 从 words 文件中找包含 "dogdogdog" 的行
[bq@shell bin]$ cat words | grep -E '(dog){3}' # (dog){3} 表示 "dog" 连续出现 3 次
# 输出:
# dogdogdog
# dogdogdogdog
2. -e
:一次匹配多个模式
理论 :当你想同时找多个关键词时,用 -e
可以指定多个匹配模式(相当于 "或" 的关系)。
示例 :同时找包含 cat
或 dog
的行
bash
[bq@shell bin]$ cat words | grep -e 'cat' -e 'dog' # -e 后面跟第一个模式,再用一个 -e 跟第二个模式
# 输出:
# cat
# category
# acat
# concatenate
# dog
# dogdog
# ...(所有含 cat 或 dog 的行)
3. -f
:从文件中读取匹配模式
理论 :如果要匹配的模式太多(比如几十上百个关键词),逐个用 -e
写太麻烦,这时可以把模式存到文件里,用 -f
让 grep
从文件读。
实验流程 :
① 创建一个存模式的文件(每行一个模式);
② 用 grep -f
读取该文件,筛选包含任一模式的行。
示例:
bash
# 步骤1:创建模式文件,包含 "cat" 和 "dog"
[bq@shell bin]$ echo -e 'cat\ndog' > patterns.txt # 用 echo -e 换行,将内容写入 patterns.txt
# 步骤2:查看模式文件内容
[bq@shell bin]$ cat patterns.txt
# 输出:
# cat
# dog
# 步骤3:从 words 中筛选包含 patterns.txt 中任一模式的行
[bq@shell bin]$ cat words | grep -f patterns.txt # -f 后面跟存模式的文件
# 输出和 -e 'cat' -e 'dog' 相同,因为模式文件里就是这两个词
4. -i
:忽略大小写
理论 :默认情况下,grep
区分大小写(比如 Cat
和 cat
会被当成不同内容),-i
可以关闭大小写区分。
示例 :找包含 cBt
(不区分大小写)的行
bash
[bq@shell bin]$ cat words | grep -i 'cBt' # -i 让匹配时忽略大小写,所以能匹配到 "cbt"
# 输出:
# cbt
5. -w
:只匹配完整单词
理论 :默认情况下,grep 'cat'
会匹配包含 cat
的所有内容(比如 category
里的 cat
),-w
只匹配 "完整单词"(前后是空格、标点或开头 / 结尾)。
示例 :只找单独的 cat
单词
bash
[bq@shell bin]$ cat words | grep -w 'cat' # 只匹配 "cat" 这个完整单词,不匹配 "category" 里的 "cat"
# 输出:
# cat
# hello cat # 这里 "cat" 是单独的词
6. -x
:只匹配完整的行
理论 :如果想找 "整行内容完全等于某个模式" 的行(而不是包含该模式),用 -x
。
示例 :只找内容正好是 cat
的行
bash
[bq@shell bin]$ cat words | grep -x 'cat' # 只有当一行内容完全是 "cat" 时才会被匹配
# 输出:
# cat # 其他行比如 "category" 因为内容不全是 "cat",所以不匹配
(二)输出控制:怎么展示筛选结果?
这部分选项用来控制筛选结果的展示形式,比如只看数量、隐藏文件名等。
1. -v
:反向匹配(显示不包含模式的行)
理论 :默认是显示 "包含模式" 的行,-v
反过来,显示 "不包含模式" 的行(相当于 "排除")。
示例 1 :排除以 d
或 c
开头的行
bash
[bq@shell bin]$ cat words | grep -v '^d|^c' # ^d 表示以 d 开头,^c 表示以 c 开头,-v 排除这些行
# 输出:
# acat # 不以 d 或 c 开头
# hello cat
示例 2:过滤配置文件中的注释和空行
bash
[bq@shell bin]$ grep -v '^ *#|^$' /etc/profile # ^ *# 表示以任意空格+#开头(注释行),^$ 表示空行,-v 排除它们
# 输出:/etc/profile 中有效的配置行(非注释、非空)
2. -m
:限制最大匹配数量
理论 :当匹配到的行太多时,用 -m 数字
可以让 grep
找到指定数量的行后就停止。
示例 :只显示前 2 个包含 dog
的行
bash
# 先看所有包含 dog 的行
[bq@shell bin]$ cat words | grep 'dog'
# 输出:
# dog
# dogdog
# dogdogdog
# dogdogdogdog
# 只显示前 2 行
[bq@shell bin]$ cat words | grep -m2 'dog' # -m2 表示最多匹配 2 行
# 输出:
# dog
# dogdog
3. -c
:统计匹配到的行数
理论 :不想看具体内容,只想知道有多少行符合条件,用 -c
直接输出数量。
示例 :统计包含 dog
的行数
bash
[bq@shell bin]$ cat words | grep -c 'dog' # -c 计算匹配到的行数
# 输出:4 (因为有 4 行包含 dog)
4. -n
:显示匹配行的行号
理论 :需要知道匹配内容在文件中的位置时,-n
会在每行前加上行号。
示例 :显示包含 cat
的行及其行号
bash
[bq@shell bin]$ cat words | grep -n 'cat' # -n 显示行号(格式:行号:内容)
# 输出:
# 1:cat # 第 1 行
# 2:category # 第 2 行
# 3:acat # 第 3 行
# ...
5. -o
:只显示匹配到的部分(不显示整行)
理论 :默认会显示整行内容,-o
只提取行中与模式匹配的部分(适合提取具体关键词)。
示例 :只提取连续 3 次 dog
的部分
bash
# 先看包含 "dogdogdog" 的整行
[bq@shell bin]$ cat words | grep -E '(dog){3}'
# 输出:
# dogdogdog
# dogdogdogdog
# 只提取匹配的部分
[bq@shell bin]$ cat words | grep -E -o '(dog){3}' # -o 只显示匹配到的 "dogdogdog"
# 输出:
# dogdogdog
# dogdogdog # 第二行中的前 3 个 dog 被提取出来
6. -q
:静默模式(只判断是否存在,不输出内容)
理论 :在脚本中常用,-q
让 grep
不显示任何结果,但可以通过系统变量 $?
判断是否匹配到(0 表示匹配到,1 表示没匹配到)。
示例 :判断是否存在连续 3 次 dog
的行
bash
# 情况1:存在匹配内容
[bq@shell bin]$ cat words | grep -q -E '(dog){3}' # -q 不输出内容
[bq@shell bin]$ echo $? # $? 是上一条命令的返回值,0 表示成功(匹配到)
# 输出:0
# 情况2:不存在匹配内容
[bq@shell bin]$ cat words | grep -q -E '(dog){3}abc' # 找 "dogdogdogabc",不存在
[bq@shell bin]$ echo $?
# 输出:1
(三)查找文件:如何在目录中递归搜索?
当需要在多个文件或目录中查找时,这些选项能帮你高效遍历。
1. -r
/ -R
:递归搜索目录
理论:
-r
:递归搜索目录下的所有文件(不跟随软链接);-R
:递归搜索,且会跟随软链接(类似访问真实文件)。
示例 :在 /etc
目录中找包含 SELINUX=
的行
bash
[bq@shell bin]$ grep -r '^SELINUX=' -s /etc # -r 递归搜索 /etc,-s 不显示权限不足的错误,^SELINUX= 匹配以 SELINUX= 开头的行
# 输出:
# /etc/selinux/config:SELINUX=disabled # 找到的结果
2. -h
/ -H
:控制是否显示文件名
理论:
-h
:只显示匹配的内容,不显示文件名;-H
:显示内容时附带文件名(默认行为)。
示例:
bash
# 不显示文件名
[bq@shell bin]$ grep -r '^SELINUX=' -s -h /etc # -h 隐藏文件名
# 输出:SELINUX=disabled
# 显示文件名(默认)
[bq@shell bin]$ grep -r '^SELINUX=' -s -H /etc # -H 显式指定显示文件名
# 输出:/etc/selinux/config:SELINUX=disabled
3. -l
/ -L
:只显示包含 / 不包含模式的文件名
理论:
-l
:只输出 "包含匹配内容" 的文件名;-L
:只输出 "不包含匹配内容" 的文件名。
示例:
bash
# 只显示包含 SELINUX= 的文件
[bq@shell bin]$ grep -r '^SELINUX=' -s -l /etc # -l 只输出文件名
# 输出:/etc/selinux/config
# 只显示不包含 SELINUX= 的文件(最后5个)
[bq@shell bin]$ grep -r '^SELINUX=' -s -L /etc | tail -5 # -L 输出不包含的文件,tail -5 取最后5个
# 输出:
# /etc/gdm/PostLogin/Default.sample
# /etc/gdm/PostSession/Default
# ...(其他不包含的文件)
(四)上下文控制:显示匹配行的前后内容
当需要查看匹配内容的 "上下文"(前后几行)时,用这些选项。
1. -B
:显示匹配行和前面的行
理论 :-B 数字
表示显示匹配行及其前面 数字
行的内容(B = Before)。
示例 :显示包含 10.1.8.88
的行及其前面 2 行
bash
[bq@shell bin]$ ip addr | grep '10.1.8.88' -B2 # -B2 显示匹配行和前面 2 行
# 输出:
# 2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ... # 前2行
# link/ether 00:0c:29:2b:c8:7a brd ... # 前1行
# inet 10.1.8.88/24 brd ... # 匹配行
2. -A
:显示匹配行和后面的行
理论 :-A 数字
表示显示匹配行及其后面 数字
行的内容(A = After)。
示例 :显示包含 ens32:
的行及其后面 2 行
bash
[bq@shell bin]$ ip addr | grep 'ens32:' -A2 # -A2 显示匹配行和后面 2 行
# 输出:
# 2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu ... # 匹配行
# link/ether 00:0c:29:2b:c8:7a brd ... # 后1行
# inet 10.1.8.88/24 brd ... # 后2行
3. -C
:显示匹配行和前后的行
理论 :-C 数字
表示显示匹配行及其前后各 数字
行的内容(C = Context)。
示例 :显示包含 10.1.8.88
的行及其前后各 2 行
bash
[bq@shell bin]$ ip addr | grep '10.1.8.88' -C2 # -C2 显示匹配行和前后各 2 行
# 输出:
# 2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu ... # 前2行
# link/ether 00:0c:29:2b:c8:7a brd ... # 前1行
# inet 10.1.8.88/24 brd ... # 匹配行
# valid_lft forever preferred_lft forever # 后1行
# inet6 fe80::5882:62aa:161b:c9c1/64 ... # 后2行
四、总结
grep
的核心是 "筛选",通过不同选项可以灵活控制匹配规则、输出形式和搜索范围。记住几个高频选项能解决大部分问题:
- 忽略大小写:
-i
- 反向匹配:
-v
- 显示行号:
-n
- 递归搜索:
-r
- 上下文查看:
-B
/-A
/-C
如涉及版权问题,请联系作者处理!!!!!