grep
搜索多个具有“或”关系的字段
在 grep 命令中,搜索多个具有“或”关系的字段(即匹配任意一个目标模式),可以通过以下几种方式实现:
1. 利用扩展正则表达式的 | 符号(推荐)
grep 支持正则表达式,其中“或”关系可以用 | 表示,但需要配合 -E 选项(启用扩展正则表达式),或直接使用 egrep(egrep 等价于 grep -E)。
语法:
grep -E '模式1|模式2|模式3' 文件名
说明:
模式1|模式2|模式3表示匹配“模式1”或“模式2”或“模式3”的行。- 单引号
'用于避免 shell 解释|符号(必须加,否则|会被 shell 当作管道符处理)。
2. 利用基本正则表达式的 \| 符号
如果不使用 -E 选项(默认是基本正则表达式),“或”关系需要用转义的 \| 表示(即 | 前加 \)。
语法:
grep '模式1\|模式2\|模式3' 文件名
3. 从文件读取多个模式(适合大量模式)
如果需要匹配的模式很多(比如几十上百个),可以将所有模式写入一个文件(每行一个模式),然后用 -f 选项让 grep 读取该文件中的模式(默认就是“或”关系)。
步骤:
- 创建模式文件(例如
patterns.txt),每行写一个需要匹配的模式:
模式1
模式2
模式3
- 使用
grep -f命令:
grep -f patterns.txt 文件名
4.直接指定多个关键字
需要注意的是,如果-e后面的模式包含空格、特殊字符(*、?、| 等)或以-开头时,必须加引号;
加单引号和双引号的区别:
- 单引号 '':完全字面量,不进行变量扩展
- 双引号 "":允许变量扩展,会解释转义字符
grep -e keyword1 -e keyword2 info.log
grep -e "keyword1" -e "keyword2" info.log
-- 变量扩展
VAR="hello"
echo '$VAR' # 输出: $VAR
echo "$VAR" # 输出: hello
搜索多个具有“且”关系的字段
使用正则
grep -n -A10 -B10 -E '关键字1.*关键字2|关键字2.*关键字1' app.log
先找到关键字对应的行号,然后根据行号sed命令打印指定行
# 先拿到行号
grep -n "关键字1" app.log | grep "关键字2"
# 假设输出是 第150行
# 然后用 sed 看上下文
sed -n '140,160p' app.log
忽略大小写
-i:忽略大小写(例如 grep -iE 'apple|Banana' test.txt 会匹配“Apple”“BANANA”等)。
显示匹配的行号
-n:显示匹配行的行号。
反向匹配
-v:反向匹配(只显示不包含任何模式的行)。
限制一行展示的字数
grep 本身的核心功能是「搜索匹配文本行」,没有直接限制“一行展示字数”的参数,但可以通过「grep 先筛选匹配行 + 其他文本工具(cut/awk/sed)后处理长度」的组合,实现两种常见需求:
- 只显示匹配行的「前 N 个字符」(截断超长行,限制展示长度);
- 只筛选出「本身长度 ≤ N 个字符」的匹配行(不显示超长匹配行)。
下面分场景给出具体实现,适配 Linux/macOS 终端(Windows 可通过 WSL 或 Git Bash 执行):
一、场景 1:显示匹配行,但只展示前 N 个字符(截断超长行)
核心逻辑:先用 grep 找到目标行,再通过 cut/awk/sed 截取前 N 个字符,限制每行展示字数。
方案 1:用 cut 截取(最简单,推荐)
cut -c 1-N 表示截取每行第 1 到第 N 个字符(-c 按字符计数,支持中文)。
示例:搜索文件 test.txt 中包含「PlantUML」的行,只展示前 50 个字符:
grep "PlantUML" test.txt | cut -c 1-50
● 解释:grep 筛选匹配行后,通过管道 | 传给 cut,-c 1-50 截取前 50 字符,超长部分直接截断。
方案 2:用 awk 截取(支持更灵活的逻辑)
substr($0, 1, N) 表示截取整行($0)从第 1 个字符开始,共 N 个字符。
示例:同上,只展示前 50 个字符,且末尾加 ... 提示截断:
grep "PlantUML" test.txt | awk '{print substr($0, 1, 50) "..." }'
● 优势:可以额外添加提示(如 ...),或判断行长度(比如“只有超长行才加提示”):
# 行长度 >50 才截断并加 ...,否则原样输出
grep "PlantUML" test.txt | awk '{if(length($0)>50) print substr($0,1,50)"..."; else print $0}'
方案 3:用 sed 正则截取(适合习惯 sed 的用户)
通过正则匹配前 N 个字符,保留匹配部分,删除后续内容。
示例:截取前 50 个字符:
grep "PlantUML" test.txt | sed 's/^\(.\{50\}\).*/\1/'
● 解释:^\(.\{50\}\).* 匹配“开头 50 个字符 + 后续所有内容”,\1 保留前 50 个字符,删除后续内容。
二、场景 2:只筛选“长度 ≤ N 个字符”的匹配行(超长匹配行直接不显示)
核心逻辑:用 awk 同时实现「匹配关键词 + 限制行长度」,直接过滤掉超长的匹配行。
示例:搜索 test.txt 中包含「PlantUML」且行长度 ≤ 80 个字符的行(超长匹配行不显示):
awk '/PlantUML/ && length($0) <= 80' test.txt
● 解释:
/PlantUML/:等价于 grep 的关键词匹配,只处理包含该字符串的行;length($0) <= 80:限制行长度(length($0)计算整行字符数)≤80;- 满足两个条件才输出,直接过滤超长匹配行。
如果需要“长度 ≤80 且显示前 50 字符”,可组合截取:
awk '/PlantUML/ && length($0) <= 80 {print substr($0,1,50)}' test.txt
三、关键注意事项
- 中文字符兼容:
cut -c、awk length()、sed .{N}均按「字符」计数(不是字节),支持中文(比如 1 个中文字符算 1 个,不会截断中文); - N 的取值:根据需求调整(如前 30 字符写
1-30,长度 ≤100 写length($0) <=100); - 管道顺序:必须先
grep筛选行,再处理长度(如果先处理长度再 grep,可能漏掉关键词在截断部分的行)。
四、常用组合总结
| 需求 | 命令示例 |
|---|---|
| 匹配行只显示前 50 字符 | `grep "关键词" 文件名 |
| 匹配行≤80字符才显示 | awk '/关键词/ && length($0)<=80' 文件名 |
| 匹配行截断前50字符+提示 | `grep "关键词" 文件名 |
通过这种“grep 筛选 + 工具截断/筛选”的组合,就能完美实现「限制一行展示字数」的需求~
浙公网安备 33010602011771号