grep(Global Regular Expression Print,全局正则表达式打印)是 Linux/Unix 系统中最核心的文本搜索工具之一,其核心功能是在文本中匹配符合正则表达式的内容,并输出匹配结果。它支持灵活的模式匹配、多文件搜索、递归处理等功能,是日常运维、代码审计、日志分析的必备工具。
grep [选项] [匹配模式] [文件/目录]
参数说明:
选项:grep 提供的各种功能子命令,如 -E 启用扩展正则表达式。
匹配模式:可以是普通字符串(默认)或正则表达式(需结合选项启用)。
文件 / 目录:指定要搜索的文件;若为目录,需配合 -r 选项递归搜索。若不指定文件,grep 会从标准输入(STDIN) 读取内容(如通过管道 | 接收其他命令的输出)。
假如我们在用户主目录的 test 目录下面创建了一个名为 example.txt 的文本文件:
hxstrive@localhost:~/test$ ll example.txt -rw-r--r-- 1 hx hx 2256 Sep 12 10:28 example.txt hxstrive@localhost:~/test$ cat example.txt A rose stood by the garden wall, Against the cold, it made a stand.Its petals, soft like silken shawl, Caught the first touch of the dawn's warm hand. The wind, a wild and restless guest, Came whistling through with a playful zest.It tousled the rose's tender head, But the rose held fast, not to be misled.
下面将基于 example.txt 文件内容来演示 grep 命令的用法。
-F 或 --fixed-strings 按固定字符串匹配(不解析正则,特殊字符如 .* 按字面处理),如 grep -F "a.b" log.txt(匹配字面量 "a.b",而非正则的 "a 任意字符 b")
hxstrive@localhost:~/test$ grep -F "d.I" example.txt Against the cold, it made a stand.Its petals, soft like silken shawl,
-E 或 --extended-regexp 启用扩展正则表达式(支持 `(){}` 等,无需转义),如: grep -E "error|warning" log.txt(匹配 "error" 或 "warning")
hxstrive@localhost:~/test$ grep -E "cold|guest" example.txt Against the cold, it made a stand.Its petals, soft like silken shawl, The wind, a wild and restless guest,
-G 或 --basic-regexp 默认模式(基础正则,|、() 等需加反斜杠转义),如:grep -G "error\|warning" log.txt(与上例功能相同,但 |需转义)
hxstrive@localhost:~/test$ grep -G "cold|guest" example.txt hxstrive@localhost:~/test$ grep -G "cold\|guest" example.txt Against the cold, it made a stand.Its petals, soft like silken shawl, The wind, a wild and restless guest,
-P 或 --perl-regexp 启用 Perl 兼容正则(支持更复杂的正则特性,如 \d 匹配数字、\s 匹配空白),如:grep -P "\d{3}-\d{4}" phone.txt(匹配 "123-4567" 格式的号码)
hxstrive@localhost:~/test$ grep -P "made\sa\sstand" example.txt Against the cold, it made a stand.Its petals, soft like silken shawl,
-i 或 --ignore-case 忽略大小写匹配,如:grep -i "hello" test.txt(匹配 "Hello" "HELLO" "hello" 等)
hxstrive@localhost:~/test$ grep -i "it" example.txt Against the cold, it made a stand.Its petals, soft like silken shawl, Came whistling through with a playful zest.It tousled the rose's tender head,
-w 或 --word-regexp 精确匹配整个单词(避免部分匹配,单词边界由非字母数字字符分隔),如:grep -w "cat" text.txt(匹配 "cat",但不匹配 "category" 或 "scat")
hxstrive@localhost:~/test$ grep -w "it" example.txt Against the cold, it made a stand.Its petals, soft like silken shawl,
-x 或 --line-regexp 整行完全匹配(仅当整行内容与模式完全一致时才输出),如:grep -x "success" result.txt(仅输出内容为 "success" 的行)
hxstrive@localhost:~/test$ grep -xP "\s" example.txt
注意,上述命令将匹配一行仅有一个空格的行。
-o 或 --only-matching 只显示匹配的内容本身(而非整行),如:grep -o "\b[0-9]\+\b" log.txt(仅提取行中的所有数字)
hxstrive@localhost:~/test$ grep "and" example.txt Against the cold, it made a stand.Its petals, soft like silken shawl, Caught the first touch of the dawn's warm hand. The wind, a wild and restless guest, hxstrive@localhost:~/test$ grep -o "and" example.txt and and and
-n 或 --line-number 显示匹配行的行号(输出格式:行号:内容),如:grep -n "error" log.txt(定位错误日志的行号)
hxstrive@localhost:~/test$ grep -n "and" example.txt 2:Against the cold, it made a stand.Its petals, soft like silken shawl, 3:Caught the first touch of the dawn's warm hand. 5:The wind, a wild and restless guest,
-H 或 --with-filename 显示匹配内容所在的文件名(多文件搜索时默认启用,单文件默认不显示),如:grep -H "test" *.txt(显示所有 .txt 文件中含 "test" 的行及对应文件名)
hxstrive@localhost:~/test$ grep -H "and" example.txt example.txt:Against the cold, it made a stand.Its petals, soft like silken shawl, example.txt:Caught the first touch of the dawn's warm hand. example.txt:The wind, a wild and restless guest,
-h 或 --no-filename 不显示文件名(与 -H 相反,多文件搜索时强制隐藏文件名),如:grep -h "test" *.txt(仅输出匹配内容,不区分来自哪个文件)
hxstrive@localhost:~/test$ grep -h "and" example.txt Against the cold, it made a stand.Its petals, soft like silken shawl, Caught the first touch of the dawn's warm hand. The wind, a wild and restless guest,
-l 或 --files-with-matches 只显示包含匹配内容的文件名(不输出具体匹配行),如:grep -l "Against the cold" *.txt(找出当前目录下含 "Against the cold" 的所有文件)
hxstrive@localhost:~/test$ grep -l "Against the cold" * example.txt
-L 或 --files-without-match 只显示不包含匹配内容的文件名(与 -l 相反),如:grep -L "test" *.sh(找出当前目录下不含 "test" 的所有脚本文件)
hxstrive@localhost:~/test$ grep -L "Against the cold" * array.json data.json
--color=auto 为匹配的内容着色(多数 Linux 系统默认开启,auto 表示仅在终端输出时着色),如:grep --color=auto "key" data.txt(匹配的 "key" 以红色高亮显示)
hxstrive@localhost:~/test$ grep --color=auto "and" example.txt Against the cold, it made a stand.Its petals, soft like silken shawl, Caught the first touch of the dawn's warm hand. The wind, a wild and restless guest,
-r 或 --recursive 递归搜索目录下的所有文件(包括子目录),如:grep -r "username" /home/(搜索 /home 下所有文件中含 "username" 的内容)
-R 与 -r 功能相同(部分系统兼容写法) 同上
hxstrive@localhost:~/test$ sudo grep -r "username" /etc/ /etc/X11/Xreset.d/README:# The username of the user logging out is provided in the $USER environment /etc/login.defs:# (for mbox use) by appending the username to MAIL_DIR as defined /etc/login.defs:# Enable display of unknown usernames when login failures are recorded. /etc/login.defs:# WARNING: Unknown usernames may become world readable. /etc/login.defs:# for private user groups, i. e. the uid is the same as gid, and username is /etc/login.defs:# the same as gid, and username is the same as the primary group name. /etc/crontab:# and files in /etc/cron.d. These files also have username fields, /etc/security/limits.conf:# the literal username root. /etc/wgetrc:#header = From: Your Name <username@site.domain>
-d <action> 或 --directories=<action> 指定处理目录的方式(read 递归、skip 跳过、grep 视为文件) ,如:grep -d skip "test" /tmp/*(搜索 /tmp 下的文件,跳过目录)
hxstrive@localhost:~/test$ sudo grep -d skip "h" /tmp/* /tmp/test.txt:hello
-include=<pattern> 仅搜索文件名匹配指定模式的文件,如:grep -r --include="*.log" "error" /var/(递归搜索 /var 下所有 .log 文件中的 "error")
hxstrive@localhost:~/test$ grep -r --include="*.txt" "and" ~/test/ /home/hx/test/example.txt:Against the cold, it made a stand.Its petals, soft like silken shawl, /home/hx/test/example.txt:Caught the first touch of the dawn's warm hand. /home/hx/test/example.txt:The wind, a wild and restless guest,
-exclude=<pattern> 排除文件名匹配指定模式的文件,如:grep -r --exclude="*.tmp" "test" /tmp/(递归搜索 /tmp,排除 .tmp 文件)
hxstrive@localhost:~/test$ grep -r --exclude="*.txt" "and" ~/test/
-exclude-dir=<pattern> 排除目录名匹配指定模式的目录,如:grep -r --exclude-dir=".git" "func" /project/(递归搜索项目目录,排除 .git目录)
-v 或 --invert-match 反向匹配(输出不包含匹配内容的所有行),如:grep -v "debug" log.txt(显示所有不含 "debug" 的日志行)
hxstrive@localhost:~/test$ grep -v "and" example.txt A rose stood by the garden wall, Came whistling through with a playful zest.It tousled the rose's tender head, But the rose held fast, not to be misled.
-c 或 --count 统计匹配的行数(注意:一行多匹配仍算 1 行),如:grep -c "success" result.txt(统计成功记录的行数)
hxstrive@localhost:~/test$ grep "and" example.txt Against the cold, it made a stand.Its petals, soft like silken shawl, Caught the first touch of the dawn's warm hand. The wind, a wild and restless guest, hxstrive@localhost:~/test$ grep -c "and" example.txt 3
-m <num> 或 --max-count=<num> 匹配到指定次数后停止搜索(提高效率,避免冗余),如:grep -m 5 "error" log.txt(找到 5 个错误行后停止搜索)
hxstrive@localhost:~/test$ grep "and" example.txt Against the cold, it made a stand.Its petals, soft like silken shawl, Caught the first touch of the dawn's warm hand. The wind, a wild and restless guest, hxstrive@localhost:~/test$ grep -m 2 "and" example.txt Against the cold, it made a stand.Its petals, soft like silken shawl, Caught the first touch of the dawn's warm hand.
-A <num> 或 --after-context=<num> 显示匹配行及后续 num 行(After context),如:grep -A 2 "error" log.txt(显示错误行及之后 2 行,用于查看错误上下文)
hxstrive@localhost:~/test$ grep -A 2 "restless" example.txt The wind, a wild and restless guest, Came whistling through with a playful zest.It tousled the rose's tender head, But the rose held fast, not to be misled.
-B <num> 或 --before-context=<num> 显示匹配行及之前 num 行(Before context),如:grep -B 1 "success" log.txt(显示成功行及之前 1 行,查看前置条件)
hxstrive@localhost:~/test$ grep -B 2 "restless" example.txt Caught the first touch of the dawn's warm hand. The wind, a wild and restless guest,
-C <num> 或 --context=<num> 显示匹配行及前后各 num 行(Context,等价于 -A num -B num),如: grep -C 1 "warning" log.txt(显示警告行及前后各 1 行,完整上下文)
hxstrive@localhost:~/test$ grep -C 2 "restless" example.txt Caught the first touch of the dawn's warm hand. The wind, a wild and restless guest, Came whistling through with a playful zest.It tousled the rose's tender head, But the rose held fast, not to be misled.
-q 或 --quiet / --silent 静默模式(不输出任何内容,仅通过退出码判断是否匹配),如:grep -q "error" log.txt && echo "有错误"(若日志含错误,输出提示)
-s 或 --no-messages 抑制错误信息(不显示 "No such file or directory" 等报错),如:grep -s "test" *.txt(搜索所有 .txt 文件,忽略不存在的文件报错)
-z 或 --null-data 将空字符(\0)视为行分隔符(用于处理含换行符的文件名或内容),如:find . -name "*.log" -print0 | xargs -0 grep -z "error"(处理含空格的文件名)
# 搜索 /var/log/syslog 中含 "ERROR" 的行,显示行号及前后各 2 行上下文,匹配内容着色 hxstrive@localhost:~/test$ grep -nC 2 --color=auto "ERROR" /var/log/syslog 93-Sep 12 09:04:04 LOCALHOST systemd[1]: landscape-client.service: Consumed 2.132s CPU time. 94-Sep 12 09:04:04 LOCALHOST dockerd[304]: time="2025-09-12T09:04:04.506080746+08:00" level=info msg="Loading containers: start." 95:Sep 12 09:04:04 LOCALHOST kernel: [ 7.682529] WSL (216) ERROR: CheckConnection: getaddrinfo() failed: -5 96-Sep 12 09:04:04 LOCALHOST kernel: [ 10.398277] kvm_intel: Using Hyper-V Enlightened VMCS 97-Sep 12 09:04:04 LOCALHOST kernel: [ 10.807581] Initializing XFRM netlink socket
# 递归搜索 /project 下所有 .c 文件中含 "initACLKeyResultCache" 的行,排除 .git 目录和 // 注释行 hxstrive@localhost:/project$ grep -r --include="*.c" --exclude-dir=".git" "initACLKeyResultCache" /project | gre p -v "//" /project/src/acl.c:void initACLKeyResultCache(aclKeyResultCache *cache) { /project/src/acl.c: initACLKeyResultCache(&cache); /project/src/acl.c: initACLKeyResultCache(&cache);
# 找出 ~/scripts 下所有 .sh 文件中含 "echo" 命令的文件(仅显示文件名) hxstrive@localhost:/project$ grep -rl --include="*.sh" "echo" ~/scripts /home/hx/scripts/显示系统变量和转义字符.sh /home/hx/scripts/使用内联重定向计算表达式.sh /home/hx/scripts/显示时间和登录者.sh /home/hx/scripts/使用自定义变量.sh /home/hx/scripts/使用方括号执行数学运算.sh /home/hx/scripts/使用expr执行数学运算.sh /home/hx/scripts/反引号的使用.sh /home/hx/scripts/exit命令.sh /home/hx/scripts/在脚本中使用bc.sh
# 查看进程列表,筛选含 "redis" 的进程(显示进程ID和命令) hxstrive@localhost:/project$ ps aux | grep -w "redis" 999 721 0.4 0.1 147316 17408 ? Ssl 10:22 1:32 redis-server *:6379 hx 3942 0.0 0.0 4028 2176 pts/0 S+ 16:22 0:00 grep --color=auto -w redis
#!/bin/bash # 检查 example.txt 是否含 "=====END=====",若不含则追加到末尾 if ! grep -q "=====END=====" example.txt; then echo "=====END=====" >> example.txt fi
将上述脚本保存到 demo.sh 中,且赋予执行权限,最后运行如下代码:
hxstrive@localhost:~/test$ ./demo.sh hxstrive@localhost:~/test$ cat example.txt A rose stood by the garden wall, Against the cold, it made a stand.Its petals, soft like silken shawl, Caught the first touch of the dawn's warm hand. The wind, a wild and restless guest, Came whistling through with a playful zest.It tousled the rose's tender head, But the rose held fast, not to be misled. =====END=====
grep 的退出状态码可用于脚本判断匹配结果,规则如下:
0:找到至少 1 个匹配项;
1:未找到任何匹配项;
2:发生错误(如文件不存在、权限不足)
示例:通过退出码判断文件是否含指定内容
#!/bin/bash grep -q "target" example.txt if [ $? -eq 0 ]; then echo "文件含 target" elif [ $? -eq 1 ]; then echo "文件不含 target" else echo "搜索出错" fi
运行下面指令,将上述脚本保存在 demo.sh 脚本,然后赋予执行权限,最后执行脚本:
hxstrive@localhost:~/test$ vim demo.sh hxstrive@localhost:~/test$ chmod +x demo.sh hxstrive@localhost:~/test$ ./demo.sh 文件不含 target