当前位置: 首页 > news >正文

grep命令要点、详解和示例

grep技术要点

1) 工作模型(3 件事)

  • 输入:从文件标准输入-)读入,一次按“行”处理(除非用 -z 改成以 NUL 作为“行”分隔)。
  • 匹配:把每一行拿去和模式(pattern)比对。模式可以是正则(BRE/ERE/PCRE)或纯文本-F)。
  • 输出:默认打印匹配到的整行;用 -o 可只打印匹配片段;用 -l/-L/-c 改为打印文件名计数
    退出码(脚本很有用):匹配到返回 0,未匹配返回 1,出错(且没 -q)返回 2

2) 模式种类 & 选型思路

  • -G(BRE,默认):基础正则。+ ? | () 在 BRE 里不是元字符,需转义:\+ \? \| \(\).
  • -E(ERE):扩展正则,+ ? | () 直接可用;日常首选,等价于历史上的 egrep
  • -F(固定字符串):把模式当“纯文本”,不解正则;最快、最稳,适合日志多关键词查找。
  • -P(Perl/PCRE):支持高级正则(如 \b、断言 (?<=x)、懒惰量词等)。有时未编进发行版,或在极大文件上稍慢——仅当确实需要这些能力再用。
    通用小抄(ERE 语义为例)
    ^ 行首;$ 行尾;. 任意单字符;* 前导重复 ≥0 次;+ ≥1 次;? 0或1;{m,n} 次数;[] 字符类;[^] 取反;() 分组;| 或;[[:alpha:]] [[:digit:]] [[:space:]]POSIX 类对多语言更稳。
    整词-w(按“字母/数字/下划线”边界)或 -P '\bword\b'
    多模式:多次 -e,或 -f pattern_file(每行一个模式)。

3) 递归与路径筛选

  • -r 递归;-R 递归且跟随符号链接。默认无文件时,递归会把“当前目录”当作输入。
  • 只搜特定文件--include='*.{c,h}'排除--exclude='*.min.js'--exclude-dir={.git,node_modules,build}
  • 搭配 -n(行号)、-H/-h(是否加文件名前缀)提升可读性。

4) 输出控制与上下文

  • 只要文件名-l(有匹配的文件);-L(没有匹配的文件)。
  • 只要数量-c只要命中片段-o(常与 -h 连用,便于做统计)。
  • 上下文-A NUM(后文)、-B NUM(前文)、-C NUM(两侧),或简写 -NUM
  • 限流-m NUM(每个文件匹配到 NUM 行就停),提高速度
  • 颜色--color=auto(或 --colour)。管道里可能被判为非 TTY,颜色会自动关闭。

5) 大文件/二进制/编码细节

  • 二进制检测触发时会出现“Binary file matches”。
    • 当你只是想按文本看:用 -a--binary-files=text
    • 忽略二进制:-I(等价 --binary-files=without-match)。
  • -z:把 NUL 当“换行”,配合 find -print0 / xargs -0 进行安全文件名流水线;-Z 输出文件名后加 NUL。
  • 速度技巧:LC_ALL=C grep -F ...(字节序比较、不开多字节;非常快,但不适合需要本地化字符类/大小写折叠的场景)。

6) 易踩的坑(超重要)

  1. 一定要正确引用模式:在 shell 里 * ? () | $ \ 都可能被解释,用单引号包裹模式最稳:'foo.*bar'
  2. BRE/ERE 转义差异:在 -G+ ? | () 需转义;改成 -E 通常更直观。
  3. -P 可用性:有些系统未启用 PCRE;脚本里用 -P 前先确认环境。
  4. 递归与链接-R 可能跟随循环链接导致慢或“走不出来”;需要时用 --exclude-dir 限制。
  5. -w 的“词边界”定义:只把字母/数字/下划线当词字符;含连字符或点号的“词”不适合 -w,改用 -P '\b' 或显式边界。
  6. 大小写与本地化-i 在多字节/本地化下可能和你以为的不完全一致;要“字节级”行为就 LC_ALL=C

7) 选型口诀

  • 纯文本多关键词-F-Ff(最快)。
  • 一般正则:优先 -E(少转义,读写性好)。
  • 需要断言/词边界-P(确认环境支持)。
  • 递归找代码-Rni --include=… --exclude-dir=…
  • 只要文件名/计数-l / -L / -c
  • 抽取值-o(必要时 -P 断言)。
  • 大文件提速-m1(命中即停)、LC_ALL=C、缩小 --include/--exclude 范围。

命令详解

主要用法如下:
grep [OPTION]... PATTERNS [FILE]...
要点:命令基本形式。PATTERNS 是要匹配的模式(可以是正则或字符串);FILE 是一个或多个文件名。
示例

grep 'error' /var/log/syslog

Search for PATTERNS in each FILE.
要点:对每个文件逐行检查模式,默认输出匹配到的整行(除非用 -o 或其它选项改变输出)。
示例

grep 'TODO' main.c util.c

Example: grep -i 'hello world' menu.h main.c
要点:示例说明 -i(忽略大小写)如何使用。
示例(同上):

grep -i 'hello world' menu.h main.c

PATTERNS can contain multiple patterns separated by newlines.
要点:一个模式文件或多行模式串中每行可视为一个独立模式;任一行匹配即为命中。
示例
假设 patterns.txt 内容为:

ERROR
WARN
FATAL

则:

grep -Ff patterns.txt app.log

会查找包含任意一行模式的日志行。

模式选择与解释

-E, --extended-regexp PATTERNS are extended regular expressions
要点:使用扩展正则(ERE)。在 ERE 中,+ ? | () {} 等元字符无需反斜杠转义,写法更直观。
示例

grep -E 'foo|bar|baz' file.txt

-F, --fixed-strings PATTERNS are strings
要点:把模式当作纯文本匹配,不解析正则,速度最快,适合关键词列表。
示例

grep -F 'a.b' file.txt   # 匹配字面 "a.b"

-G, --basic-regexp PATTERNS are basic regular expressions
要点:使用基本正则(BRE,很多系统默认)。在 BRE 中某些元字符(如 + ? | ())需要转义。
示例

grep -G 'foo\|bar' file.txt   # 在 BRE 中 "或" 用 \|

-P, --perl-regexp PATTERNS are Perl regular expressions
要点:启用 PCRE(Perl 风格正则),支持断言、\b、懒惰量词等高级特性。注意并非所有系统都启用了 -P
示例

grep -Po '(?<=ID=)\d+' data.txt   # 提取 ID= 后的数字

-e, --regexp=PATTERNS use PATTERNS for matching
要点:显式指定一个模式;可重复使用 -e 指定多个模式;适合模式以 - 开头时避免被误解析为选项。
示例

grep -e '^Error' -e '^Warning' logfile

-f, --file=FILE take PATTERNS from FILE
要点:从文件读取多个模式(文件每行一个模式),和 -e 等效但便于管理大量模式。
示例

grep -Ff keywords.txt big.log

-i, --ignore-case ignore case distinctions in patterns and data
要点:忽略大小写匹配(模式与数据均不区分大小写)。
示例

grep -i 'linux' README

--no-ignore-case do not ignore case distinctions (default)
要点:恢复区分大小写(这是默认行为),通常无需显式指定。
示例

grep --no-ignore-case 'Makefile' files.list

-w, --word-regexp match only whole words
要点:匹配完整单词,单词边界按“字母/数字/下划线”定义。连字符或点不被视为词字符。
示例

grep -w 'is' file.txt   # 不会匹配 "this"

-x, --line-regexp match only whole lines
要点:行内容必须完全等于模式才匹配(整行匹配)。
示例

grep -x 'enabled=true' config.txt

-z, --null-data a data line ends in 0 byte, not newline
要点:把 NUL(\0)当作行分隔符而非换行,用于处理包含换行的记录或与 find -print0xargs -0 联动时更安全。
示例

# 与 -Z/-0 搭配用于 NUL 安全的文件名流
find . -type f -print0 | xargs -0 grep -z 'pattern'

杂项

-s, --no-messages suppress error messages
要点:抑制错误输出(如权限错误或不存在的文件),脚本中用于避免噪音。
示例

grep -s 'secret' /root/*

-v, --invert-match select non-matching lines
要点:反选,输出不匹配模式的行,用于过滤包含某关键词的行之外的内容。
示例

grep -v 'DEBUG' app.log

-V, --version display version information and exit
要点:显示 grep 的版本然后退出。
示例

grep -V

--help display this help text and exit
要点:显示帮助文本并退出。
示例

grep --help

输出控制

-m, --max-count=NUM stop after NUM selected lines
要点:在每个输入文件上匹配到 NUM 行后停止处理该文件(提高速度、用于“是否存在”检查)。
示例

grep -m1 'fatal' big.log

-b, --byte-offset print the byte offset with output lines
要点:输出每个匹配行在文件中的字节偏移(从 0 开始),便于定位二进制或精确定位。
示例

grep -bn 'pattern' file.txt

-n, --line-number print line number with output lines
要点:输出匹配行的行号(文件名:行号:内容)。
示例

grep -n 'TODO' src/*.c

--line-buffered flush output on every line
要点:开启逐行刷新,适用于实时管道(但会降低性能)。
示例

tail -f app.log | grep --line-buffered 'ERROR'

-H, --with-filename print file name with output lines
要点:在输出前加上文件名;在多文件搜索时默认启用,但可强制显示。
示例

grep -H 'alloc' src/*.c

-h, --no-filename suppress the file name prefix on output
要点:不显示文件名(适合单文件或只想要匹配行本身)。
示例

grep -h 'pattern' file1 file2

--label=LABEL use LABEL as the standard input file name prefix
要点:当从标准输入读取时,用给定标签代替文件名显示,便于记录来源。
示例

cat data | grep --label=STDIN -H 'pattern'

-o, --only-matching show only nonempty parts of lines that match
要点:只输出匹配到的子串,不输出整行。常用于抽取 URL、数字、键值等。
示例

grep -Eo 'https?://[^ ]+' page.html

-q, --quiet, --silent suppress all normal output
要点:静默模式,不打印任何匹配内容,用退出码判断是否存在匹配(适合脚本判断)。
示例

if grep -q 'READY' status.txt; then echo OK; fi

--binary-files=TYPE assume that binary files are TYPE; TYPE is 'binary', 'text', or 'without-match'
要点:设置遇到二进制文件时的处理策略:

  • binary:按二进制对待(默认;匹配时通常显示 “Binary file matches”);
  • text:把二进制当作文本处理;
  • without-match:把二进制视为没有匹配(忽略)。
    示例
grep --binary-files=text 'PNG' image.bin
grep --binary-files=without-match 'pattern' *

-a, --text equivalent to --binary-files=text
要点:等价于把二进制文件当作文本处理。
示例

grep -a 'TODO' file.bin

-I equivalent to --binary-files=without-match
要点:等价于把二进制文件视为不匹配(忽略)。
示例

grep -I 'pattern' *

-d, --directories=ACTION how to handle directories; ACTION is 'read', 'recurse', or 'skip'
要点:指定当遇到目录时的处理方式:

  • read:把目录当文件读(很少用);
  • recurse:进入目录递归搜索;
  • skip:跳过目录。
    示例
grep -d skip 'needle' .

-D, --devices=ACTION how to handle devices, FIFOs and sockets; ACTION is 'read' or 'skip'
要点:控制如何处理设备、FIFO、套接字,避免阻塞或不必要读取。
示例

grep -D skip -R 'pattern' /

-r, --recursive like --directories=recurse
要点:递归搜索目录(等同 --directories=recurse)。默认不跟随符号链接。
示例

grep -rn 'TODO' src/

-R, --dereference-recursive likewise, but follow all symlinks
要点:递归并跟随所有符号链接(注意可能形成循环,需要配合 --exclude-dir 限制)。
示例

grep -Rni --exclude-dir=.git 'init' .

--include=GLOB search only files that match GLOB (a file pattern)
要点:只在匹配指定文件名模式的文件中搜索,有助于提速并限制范围。支持通配如 *.c{*.c,*.h}
示例

grep -Rni --include='*.{c,h,cpp}' 'allocator' .

--exclude=GLOB skip files that match GLOB
要点:排除符合该模式的文件(如 .min.js、二进制等)。
示例

grep -Rni --exclude='*.min.js' 'fetch' web/

--exclude-from=FILE skip files that match any file pattern from FILE
要点:从文件读取排除模式列表(每行一个 GLOB),便于管理复杂排除规则。
示例

grep -Rni --exclude-from=.greprules 'needle' .

--exclude-dir=GLOB skip directories that match GLOB
要点:排除指定目录(常用 .gitnode_modulesbuild 等)。
示例

grep -Rni --exclude-dir={.git,node_modules,dist} 'config' .

-L, --files-without-match print only names of FILEs with no selected lines
要点:只列出没有匹配的文件名,常用于查找缺失项(如缺少版权头的文件)。
示例

grep -RL 'Copyright' src/

-l, --files-with-matches print only names of FILEs with selected lines
要点:只列出匹配的文件名(方便后续批处理)。
示例

grep -Rl 'panic' /var/log

-c, --count print only a count of selected lines per FILE
要点:对每个文件输出匹配行数,不显示具体行。
示例

grep -Rc 'ERROR' logs/

-T, --initial-tab make tabs line up (if needed)
要点:输出格式对齐(在带文件名前缀时用 Tab 对齐)。
示例

grep -TnH 'pattern' *.txt

-Z, --null print 0 byte after FILE name
要点:在文件名后输出 NUL(\0),便于以 NUL 为分隔的管道安全处理,例如与 xargs -0 联动。
示例

grep -Zl 'needle' -R . | xargs -0 -I{} echo "FOUND: {}"

上下文控制

-B, --before-context=NUM print NUM lines of leading context
要点:输出匹配行以及该行之前的 NUM 行,便于查看上下文。
示例

grep -B 2 'OutOfMemoryError' app.log

-A, --after-context=NUM print NUM lines of trailing context
要点:输出匹配行以及之后的 NUM 行。
示例

grep -A 2 'OutOfMemoryError' app.log

-C, --context=NUM print NUM lines of output context
要点-C NUM 等价于同时指定 -B NUM-A NUM,显示匹配行前后 NUM 行。
示例

grep -C 3 'OutOfMemoryError' app.log

-NUM same as --context=NUM
要点:简写形式,例如 -3 相当于 -C 3
示例

grep -R3 'failed' logs/

--group-separator=SEP print SEP on line between matches with context
要点:当多组匹配(有上下文)时,在组间插入自定义分隔符 SEP。默认分隔是 --
示例

grep -C1 --group-separator='-----' 'error' app.log

--no-group-separator do not print separator for matches with context
要点:取消组间分隔(把多个匹配块连续显示)。
示例

grep -C2 --no-group-separator 'warn' app.log

--color[=WHEN], --colour[=WHEN] use markers to highlight the matching strings; WHEN is 'always', 'never', or 'auto'
要点:为匹配部分加颜色标记。WHEN 参数控制启用时机:always 总是启用,never 禁用,auto 在交互式终端时启用。
示例

grep --color=auto -n 'main' *.c

-U, --binary do not strip CR characters at EOL (MSDOS/Windows)
要点:不要去掉行尾 \r(在处理 CRLF 文件时保留回车字符),便于诊断 Windows 格式换行问题。
示例

grep -U '$' windows.txt | cat -A   # 显示 ^M 等

输入 / 默认行为 / 退出状态

When FILE is '-', read standard input.
要点:将文件名指定为 - 表示从标准输入读取数据。
示例

echo "hello" | grep 'h' -    # "-" 表示 stdin

With no FILE, read '.' if recursive, '-' otherwise.
要点:未指定文件名时,如果使用递归选项(如 -r),grep 默认对当前目录 . 进行递归搜索;否则默认读取标准输入。
示例

grep -R 'pat'      # 等同 grep -R 'pat' .
echo "abc" | grep 'a'   # 无文件且不递归 → 读 stdin

With fewer than two FILEs, assume -h.
要点:当输入的文件少于两个时(例如单个文件或标准输入),默认不打印文件名前缀,相当于 -h
示例

grep 'pattern' single_file.txt   # 不显示文件名前缀

Exit status is 0 if any line is selected, 1 otherwise; if any error occurs and -q is not given, the exit status is 2.
要点:退出码含义:

  • 0:至少有一行匹配;
  • 1:没有匹配;
  • 2:发生错误(例如无法读取文件),除非使用 -q(静默)。
    脚本中常用 grep 的退出码做条件判断。
    示例
if grep -q 'READY' status.txt; then echo OK; else echo NOT_READY; fi

附 — 常见组合示例

  1. 在代码目录中递归查找包含 alloc.c/.h 文件,排除 .gitbuild
grep -Rni --include='*.{c,h,cpp}' --exclude-dir={.git,build} 'alloc' .
  1. 统计项目中每个文件的 ERROR 出现次数:
grep -Rc 'ERROR' logs/
  1. 从标准输入抽取所有 URL:
curl -s http://example.com | grep -Eo 'https?://[^ ]+'
  1. 找出没有版权声明的源文件:
grep -RL 'Copyright' src/
  1. 用 NUL 安全方式查找并处理文件名(与 xargs -0 配合):
grep -Zl 'needle' -R . | xargs -0 -I{} echo "FOUND: {}"
  1. 只查找以数字 ID 出现的位置(PCRE 断言):
grep -Po '(?<=ID=)\d+' data.txt

用法示例

看完能独立写出常用 90% 场景的 grep 命令。

A. 基础检索

# 在两个文件里找 hello world(忽略大小写)
grep -i 'hello world' menu.h main.c
  • -i:大小写不敏感。找到了就打印整行
# 在当前目录递归找包含 "TODO" 的行,并显示 文件名:行号:内容
grep -Rni --include='*.{c,h,cpp}' 'TODO' .
  • -R:递归且跟随链接;-n:行号;-H 默认在多文件时会加文件名;--include 缩小范围以提速。

B. 选择合适的模式类型

# ERE:函数名(带括号),更符合直觉
grep -REn 'my_func\(' src/
  • 在 ERE 下 ( 不是特殊字符,但 \( 可读性更好,避免歧义;若在 BRE(默认 -G)里则 必须\(
# 纯文本多关键词(最快):把关键词写到文件里,每行一个
grep -Ff keywords.txt -R --include='*.log' -n .
# PCRE:用词边界和后行断言抽取 ID
grep -aPo '(?<=ID=)\d+' big.bin
  • -a 把潜在二进制当文本;-P 支持断言;-o 只输出匹配片段(纯数字 ID)。

C. 输出控制(文件名、计数、仅匹配)

# 只列出含有匹配的文件名
grep -Rl 'panic' /var/log
# 只列出没有匹配的文件名(比如找“缺少版权头”的源文件)
grep -RL 'Copyright .* MyCorp' src/
# 只统计每个文件匹配行数
grep -Rc 'ERROR' logs/
# 只输出匹配到的关键词,便于统计频次
grep -Rho --include='*.py' -E 'TODO|FIXME' . | sort | uniq -c | sort -nr

D. 反选与上下文

# 反选:输出不含 DEBUG 的行
grep -Rnv --include='*.log' 'DEBUG' logs/# 上下文:匹配行前后各 3 行
grep -RniC3 'OutOfMemoryError' logs/
# 或写成:grep -Rni -A3 -B3 'OutOfMemoryError' logs/

E. 性能与停止条件

# 每个文件匹配到第一行就停(定位“是否存在”)
grep -m1 -R 'needle' .
# 大量固定字符串,极致提速
LC_ALL=C grep -F --include='*.txt' -R -n -e 'foo' -e 'bar' -e 'baz' .

F. 二进制与 NUL 安全流水线

# 把二进制当文本搜
grep -aR 'PNG' .
# 和 find/xargs 进行 NUL 安全联动,只输出匹配的文件名(以 NUL 结尾)
find . -type f -name '*.txt' -print0 \
| xargs -0 grep -Zl 'needle' \
| tr '\0' '\n'   # 仅为了人眼阅读

G. 目录/设备处理与排除

# 跳过特定目录,避免巨慢
grep -Rni --exclude-dir={.git,node_modules,dist,build} 'register' .# 处理目录/设备的策略
grep -D skip -d recurse -R 'pattern' .
  • -d/--directories:遇到目录 read/recurse/skip
  • -D/--devices:遇到设备/FIFO/socket read/skip

H. 脚本里更健壮

# 静默测试(只看退出码)
if grep -qE '^(enabled|on|true)$' config.txt; thenecho "feature enabled"
fi
  • -q 静默;-E 用扩展正则;配合退出码 0/1/2 做逻辑分支。
http://www.dtcms.com/a/336912.html

相关文章:

  • 基于nvm安装管理多个node.js版本切换使用(附上详细安装使用图文教程+nvm命令大全)
  • QT第九讲- 控件委托
  • Git智能合并机制深度解析
  • ChatGPT-5 对教育行业的影响与案例研究
  • Qt笔试题
  • 录像视频删除如何恢复?手机电脑的录像恢复技巧
  • 给linux的root磁盘扩容
  • 手游搬砖对云手机的需求有哪些?
  • 机器学习实例应用
  • 获粤港澳大湾区碳足迹认证:遨游智能三防手机赋能绿色通信
  • VLN视觉语言导航(3)——神经网络的构建和优化 2.3
  • 二十八、案例-部门管理-查询
  • Android中flavor的使用
  • 项目实战——矿物识别系统(利用机器学习从化学元素数据中识别矿物,从数据到分类模型)
  • 咨询进阶——解读咨询顾问技能模型
  • NL2SQL 技术深度解析与项目实践
  • Jmeter对图片验证码的处理
  • single cell ATAC(5)使用ArchR聚类
  • CentOS 7.9 部署 filebrowser 文件管理系统
  • 深入解析 Qwen3 GSPO:一种稳定高效的大语言模型强化学习算法
  • 运维命令基础
  • 算法魅力-BFS解决多源最短路
  • PPT生成视频的AI大模型应用技巧
  • 基于51单片机霍尔测速仪表测转速调速系统设计
  • Java 大视界 -- Java 大数据在智能安防视频监控系统中的视频内容理解与智能预警升级(401)
  • Java封装
  • Orange的运维学习日记--45.Ansible进阶之文件部署
  • Rust 入门 生命周期-next2 (十九)
  • Kubernetes配置管理全攻略:ConfigMap与Secret详解
  • [机器学习]10-基于ID3决策树算法的西瓜数据集分类