grep 命令基础用法
文章目录
- [grep 命令基础用法](#grep 命令基础用法)
-
- [grep 命令语法](#grep 命令语法)
- [grep 命令选项](#grep 命令选项)
-
- 模式选择和解释选项
-
- [-E 选项](#-E 选项)
- [-e 选项](#-e 选项)
- [-f 选项](#-f 选项)
- [-i 选项](#-i 选项)
- [-w 选项](#-w 选项)
- [-x 选项](#-x 选项)
- 输出控制选项
-
- [-v 选项](#-v 选项)
- [-m 选项](#-m 选项)
- [-c 选项](#-c 选项)
- [-b 选项](#-b 选项)
- [-n 选项](#-n 选项)
- [-o 选项](#-o 选项)
- [-q 选项](#-q 选项)
- [-s 选项](#-s 选项)
- 查找文件选项
- 输出内容控制选项
-
- [-B 选项](#-B 选项)
- [-A 选项](#-A 选项)
- [-C 选项](#-C 选项)
grep 是 Linux 系统中最重要的命令之一,其功能是从文本文件或管道数据流中筛选匹配的行及数据。
Linux操作文本的三大利器,简称三剑客,分别是:
- grep:擅长过滤。
- sed:擅长修改文本。
- awk:擅长格式化输出。
grep 命令语法
- 过滤管道:
command | grep [OPTION]... PATTERNS - 过滤文件:
grep [OPTION]... PATTERNS [FILE]...
grep 命令帮助信息如下:
bash
[root@server bin]$ grep --help
Usage: grep [OPTION]... PATTERNS [FILE]...
Search for PATTERNS in each FILE.
Example: grep -i 'hello world' menu.h main.c
PATTERNS can contain multiple patterns separated by newlines.
Pattern selection and interpretation:
-E, --extended-regexp PATTERNS are extended regular expressions
-F, --fixed-strings PATTERNS are strings
-G, --basic-regexp PATTERNS are basic regular expressions
-P, --perl-regexp PATTERNS are Perl regular expressions
-e, --regexp=PATTERNS use PATTERNS for matching
-f, --file=FILE take PATTERNS from FILE
-i, --ignore-case ignore case distinctions in patterns and data
--no-ignore-case do not ignore case distinctions (default)
-w, --word-regexp match only whole words
-x, --line-regexp match only whole lines
-z, --null-data a data line ends in 0 byte, not newline
Miscellaneous:
-s, --no-messages suppress error messages
-v, --invert-match select non-matching lines
-V, --version display version information and exit
--help display this help text and exit
Output control:
-m, --max-count=NUM stop after NUM selected lines
-b, --byte-offset print the byte offset with output lines
-n, --line-number print line number with output lines
--line-buffered flush output on every line
-H, --with-filename print file name with output lines
-h, --no-filename suppress the file name prefix on output
--label=LABEL use LABEL as the standard input file name prefix
-o, --only-matching show only nonempty parts of lines that match
-q, --quiet, --silent suppress all normal output
--binary-files=TYPE assume that binary files are TYPE;
TYPE is 'binary', 'text', or 'without-match'
-a, --text equivalent to --binary-files=text
-I equivalent to --binary-files=without-match
-d, --directories=ACTION how to handle directories;
ACTION is 'read', 'recurse', or 'skip'
-D, --devices=ACTION how to handle devices, FIFOs and sockets;
ACTION is 'read' or 'skip'
-r, --recursive like --directories=recurse
-R, --dereference-recursive
likewise, but follow all symlinks
--include=GLOB search only files that match GLOB (a file pattern)
--exclude=GLOB skip files that match GLOB
--exclude-from=FILE skip files that match any file pattern from FILE
--exclude-dir=GLOB skip directories that match GLOB
-L, --files-without-match print only names of FILEs with no selected lines
-l, --files-with-matches print only names of FILEs with selected lines
-c, --count print only a count of selected lines per FILE
-T, --initial-tab make tabs line up (if needed)
-Z, --null print 0 byte after FILE name
Context control:
-B, --before-context=NUM print NUM lines of leading context
-A, --after-context=NUM print NUM lines of trailing context
-C, --context=NUM print NUM lines of output context
-NUM same as --context=NUM
--group-separator=SEP use SEP as a group separator
--no-group-separator use empty string as a group separator
--color[=WHEN],
--colour[=WHEN] use markers to highlight the matching strings;
WHEN is 'always', 'never', or 'auto'
-U, --binary do not strip CR characters at EOL (MSDOS/Windows)
When FILE is '-', read standard input. With no FILE, read '.' if
recursive, '-' otherwise. With fewer than two FILEs, assume -h.
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.
Report bugs to: bug-grep@gnu.org
GNU grep home page: <http://www.gnu.org/software/grep/>
General help using GNU software: <https://www.gnu.org/gethelp/>
grep 命令选项
模式选择和解释选项
-E 选项
支持扩展正则表达式,相当于 egrep 命令。
bash
[root@server ~]$ cat words | grep -E '(dog){3}'
# 或者
[root@server ~]$ cat words | egrep '(dog){3}'
dogdogdog
dogdogdogdog
-e 选项
使用多个 -e 选项匹配多个PATTERNS。
bash
[root@server ~]$ cat words | grep -e 'cat' -e 'dog'
# 或者
[root@server ~]$ cat words | egrep 'cat|dog'
cat
category
acat
concatenate
dog
dogdog
dogdogdog
dogdogdogdog
hello cat
-f 选项
从文件读取多个 PATTERNS。
bash
[root@server ~]$ echo -e 'cat\ndog' > pattens_file
[root@server ~]$ cat pattens_file
cat
dog
[root@server ~]$ cat words | grep -f pattens_file
cat
category
acat
concatenate
dog
dogdog
dogdogdog
dogdogdogdog
hello cat
-i 选项
忽略大小写匹配。
bash
[root@server ~]$ cat words | grep -i 'cBt'
cbt
-w 选项
匹配整个单词。
bash
[root@server ~]$ cat words | grep -w 'cat'
# 或者
[root@server ~]$ cat words | grep '\bcat\b'
cat
hello cat
-x 选项
匹配整行。
bash
[root@server ~]$ cat words | grep -x 'cat'
# 或者
[root@server ~]$ cat words | grep '^cat$'
cat
输出控制选项
-v 选项
反向匹配,显示与PATTERNS不匹配的项目。
bash
[root@server ~]$ cat words | egrep -v '^d|^c'
acat
hello cat
# 不看注释行和空白行
[root@server ~]$ egrep -v '^\s*#|^$' /etc/profile
-m 选项
控制最大匹配数目,匹配特定次数后停止匹配。
bash
[root@server ~]$ cat words | grep 'dog'
dog
dogdog
dogdogdog
dogdogdogdog
[root@server ~]$ cat words | grep -m2 'dog'
dog
dogdog
-c 选项
显示匹配到项目的数量。
bash
[root@server ~]$ cat words | grep -c 'dog'
4
-b 选项
显示匹配项目的字节偏移量。
bash
[root@server ~]$ head -5 words
cat
category
acat
concatenate
dog
[root@server ~]$ cat words | grep -b 'cat'
0:cat
4:category
13:acat
18:concatenate
109:hello cat
-n 选项
显示匹配项目的行号。
bash
[root@server ~]$ cat words | grep -n 'cat'
1:cat
2:category
3:acat
4:concatenate
19:hello cat
-o 选项
只显示匹配到的内容,行中其他内容不显示。
bash
[root@server ~]$ cat words | egrep '(dog){3}'
dogdogdog
dogdogdogdog
[root@server ~]$ cat words | egrep -o '(dog){3}'
dogdogdog
dogdogdog
-q 选项
不显示任何正常输出。一般用于脚本判定文件中是否包含特定内容。
通过特殊变量 $? 查看是否匹配到内容。
bash
# 找到的情况
[root@server ~]$ cat words | egrep -q '(dog){3}'
[root@server ~]$ echo $?
0
# 找不到的情况
[root@server ~]$ cat words | egrep -q '(dog){3}asdfasfdasf'
[root@server ~]$ echo $?
1
-s 选项
不显示任何错误输出。
bash
[root@server ~]$ grep '^SELINUX=' /etc/shadow /etc/selinux/config
grep: /etc/shadow: Permission denied
/etc/selinux/config:SELINUX=disabled
[root@server ~]$ grep -s '^SELINUX=' /etc/shadow /etc/selinux/config
/etc/selinux/config:SELINUX=disabled
查找文件选项
-r -R 选项
-r,递归匹配目录。-R,递归匹配目录,跟随软链接。
bash
[root@server ~]$ grep -r '^SELINUX=' -s /etc
/etc/selinux/config:SELINUX=disabled
-h 和 -H 选项
-h,不显示匹配项目所在文件的文件名。-H,显示匹配项目所在文件的文件名,默认情况使用该选项。
bash
[root@server ~]$ grep -r '^SELINUX=' -s -h /etc
SELINUX=disabled
[root@server ~]$ grep -r '^SELINUX=' -s -H /etc
/etc/selinux/config:SELINUX=disabled
-l 和 -L 选项
-l,对目录匹配时,只显示那些包含匹配模式的文件的名称。-L,对目录匹配时,只显示那些不包含匹配模式的文件的名称。
bash
[root@server ~]$ grep -r '^SELINUX=' -s -l /etc
/etc/selinux/config
[root@server ~]$ grep -r '^SELINUX=' -s -L /etc | tail -5
/etc/gdm/PostLogin/Default.sample
/etc/gdm/PostSession/Default
/etc/gdm/PreSession/Default
/etc/gdm/custom.conf
/etc/nfs.conf
要使用 grep 搜索包含特定文本的文件,需结合其递归搜索、匹配模式等参数实现。以下是具体方法和示例:
核心用法
1. 搜索单个文件
bash
grep "特定文本" 文件名
示例:搜索 file.txt 中包含 "hello" 的行
bash
grep "hello" file.txt
2. 搜索多个文件
bash
grep "特定文本" 文件1 文件2 文件3
示例:搜索 a.txt 和 b.txt 中包含 "world" 的行
bash
grep "world" a.txt b.txt
3. 递归搜索目录下的所有文件
使用 -r(或 -R,大小写敏感一致)参数递归搜索目录:
bash
grep -r "特定文本" 目录路径
示例:递归搜索当前目录下所有文件中包含 "error" 的行
bash
grep -r "error" .
常用参数
-i
:忽略大小写匹配
bash
grep -i "Hello" file.txt # 匹配 hello/HELLO/Hello 等
-n
:显示匹配行的行号
bash
grep -n "test" file.txt # 输出如:5:this is a test line
-l
:仅显示包含匹配内容的文件名(而非具体行)
bash
grep -rl "debug" ./logs # 列出 logs 目录下含"debug"的文件
-v
:反向匹配(显示不包含特定文本的行)
bash
grep -v "ignore" file.txt # 输出不含"ignore"的行
-E
:启用扩展正则表达式(匹配复杂模式)
bash
grep -E "error|warning" file.txt # 匹配 error 或 warning
-F
:将搜索内容视为固定字符串(避免正则符号转义)
bash
grep -F "a*b" file.txt # 匹配字面量 a*b,而非正则
高级用法
1. 搜索包含多个关键词的文件
bash
# 匹配同时包含"foo"和"bar"的行
grep "foo" file.txt | grep "bar"
# 匹配包含"foo"或"bar"的行(用扩展正则)
grep -E "foo|bar" file.txt
2. 搜索二进制文件中的文本
bash
grep -a "text" binary_file # -a 把二进制文件视为文本文件
3. 排除某些文件 / 目录
bash
# 递归搜索时排除 .log 文件
grep -r --exclude="*.log" "test" .
# 排除指定目录(如 node_modules)
grep -r --exclude-dir="node_modules" "import" .
示例:实战场景
bash
# 递归搜索当前项目中含"TODO"的文件,并显示行号
grep -rn "TODO" ./src
# 查找所有 .md 文件中包含"Linux"的文件名
grep -l "Linux" *.md
# 搜索日志文件中不含"INFO"的行(即只看错误/警告)
grep -v "INFO" app.log
通过组合以上参数,可灵活满足不同的搜索需求。
输出内容控制选项
bash
[root@server ~ 10:45:09]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:fe:16:ee brd ff:ff:ff:ff:ff:ff
inet 10.1.8.10/24 brd 10.1.8.255 scope global noprefixroute ens32
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fefe:16ee/64 scope link
valid_lft forever preferred_lft forever
-B 选项
显示匹配项目本身,以及前多少行。
bash
[root@server ~ 10:58:37]# ip addr | grep '10.1.8.10' -B1
link/ether 00:0c:29:fe:16:ee brd ff:ff:ff:ff:ff:ff
inet 10.1.8.10/24 brd 10.1.8.255 scope global noprefixroute ens32
-A 选项
显示匹配项目本身,以及后多少行。
bash
[root@server ~ 11:00:44]# ip addr | grep 'ens32:' -A1
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:fe:16:ee brd ff:ff:ff:ff:ff:ff
-C 选项
显示匹配项目本身,以及前后多少行。
bash
[root@server ~ 10:59:37]# ip addr | grep '10.1.8.10' -C2
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:fe:16:ee brd ff:ff:ff:ff:ff:ff
inet 10.1.8.10/24 brd 10.1.8.255 scope global noprefixroute ens32
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fefe:16ee/64 scope link