grep

搜索多个具有“或”关系的字段

grep 命令中,搜索多个具有“或”关系的字段(即匹配任意一个目标模式),可以通过以下几种方式实现:

1. 利用扩展正则表达式的 | 符号(推荐)

grep 支持正则表达式,其中“或”关系可以用 | 表示,但需要配合 -E 选项(启用扩展正则表达式),或直接使用 egrepegrep 等价于 grep -E)。
语法:
grep -E '模式1|模式2|模式3' 文件名

说明:

  • 模式1|模式2|模式3 表示匹配“模式1”或“模式2”或“模式3”的行。
  • 单引号 ' 用于避免 shell 解释 | 符号(必须加,否则 | 会被 shell 当作管道符处理)。

2. 利用基本正则表达式的 \| 符号

如果不使用 -E 选项(默认是基本正则表达式),“或”关系需要用转义的 \| 表示(即 | 前加 \)。
语法:
grep '模式1\|模式2\|模式3' 文件名

3. 从文件读取多个模式(适合大量模式)

如果需要匹配的模式很多(比如几十上百个),可以将所有模式写入一个文件(每行一个模式),然后用 -f 选项让 grep 读取该文件中的模式(默认就是“或”关系)。
步骤:

  1. 创建模式文件(例如 patterns.txt),每行写一个需要匹配的模式:
模式1
模式2
模式3
  1. 使用 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)后处理长度」的组合,实现两种常见需求:

  1. 只显示匹配行的「前 N 个字符」(截断超长行,限制展示长度);
  2. 只筛选出「本身长度 ≤ 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

三、关键注意事项

  1. 中文字符兼容:cut -cawk length()sed .{N} 均按「字符」计数(不是字节),支持中文(比如 1 个中文字符算 1 个,不会截断中文);
  2. N 的取值:根据需求调整(如前 30 字符写 1-30,长度 ≤100 写 length($0) <=100);
  3. 管道顺序:必须先 grep 筛选行,再处理长度(如果先处理长度再 grep,可能漏掉关键词在截断部分的行)。

四、常用组合总结

需求 命令示例
匹配行只显示前 50 字符 `grep "关键词" 文件名
匹配行≤80字符才显示 awk '/关键词/ && length($0)<=80' 文件名
匹配行截断前50字符+提示 `grep "关键词" 文件名

通过这种“grep 筛选 + 工具截断/筛选”的组合,就能完美实现「限制一行展示字数」的需求~

posted on 2026-07-17 10:46  斜月三星一太阳  阅读(11)  评论(0)    收藏  举报