linux grep命令
Grep 是 Global Regular Expression Print 的缩写。
它搜索指定文件的内容,匹配指定的模式,默认情况下输出匹配内容所在的行。注意,grep 只支持匹配而不能替换匹配到的内容。
基本语法
语法格式:
grep [OPTIONS] PATTERN [FILE1 FILE2 ...]
grep [OPTIONS] [-e PATTERN | -f FILE1] [FILE2 ...]
grep 支持不同的匹配模式,比如默认的 BRE 模式,增强型的 ERE 模式,还有更强悍的 PRE 模式。
普通情况下使用默认的 BRE(basic regular expression) 模式就可以了,这种方式的特点是支持的正则表达式语法有限。如果需要更进一步的正则表达式语法支持,可以使用 ERE(extended regular expression) 模式。如果要使用复杂的正则表达式语法,可以使用 PRE 模式,它支持 Perl 语言的正则表达式语法。
常用选项:
--help -V, --version -G, --basic-regexp BRE 模式,也是默认的模式 -E, --extended-regexp ERE 模式 -P, --perl-regexp PRE 模式 -F, --fixed-strings 指定的模式被解释为字符串
-f, --file=FILE 从文件中读取正则表达式 -i 忽略大小写 -o 只输出匹配到的部分(而不是整个行) -v 反向选择,即输出没有没有匹配的行 -c 计算找到的匹配行的次数 -n 顺便输出行号
BRE正则表达式:
需要注意的是,在基本正则表达式(BRE)中,如+、{、|、( 和 )等,已经失去了它们原本的含义,而若要恢复它们原本的含义,则要在之前添加反斜杠 \,如 \+、\{、\|、\( 和 \)。
如果表达式中包含特殊字符,最好使用双引号将表达式包起来,否则会有异常,当然如果是单纯的普通字符串,则不需要
与 BRE 相比 ERE 最大的优点是支持更多的元字符,也就是在使用这些字符时不需要 \ 了。比如 BRE 中使用的 \ 符可以全部去掉。
语法 | 说明 | 解释 |
. | 匹配一个任意的字符 | 在 [] 中 . 号并不是元字符 |
^ | 行的起始 | ^ 和 $ 匹配的是一个位置而不是具体的文本 |
$ | 行的结束 | ^ 和 $ 匹配的是一个位置而不是具体的文本 |
* | 匹配 0 次或多次 | 不匹配上一次表达式,匹配上一次或匹配多次,并生成所有可能的匹配 匹配尽可能多的次数,如果实在无法匹配,也不要紧 |
[] | 匹配若干个字符之一 | 又叫字符组、字符类,比如 [0-9]、[a-z]、[A-Z] 只有在字符组内部 - 才是元字符,表示一个范围 |
[^...] | 排除型字符组 | 字符组以 ^ 开头,它会匹配一个任何未列出的字符 |
\? | 可选元素 | 在 BRE 中需要使用转义符 \ 出现一次或者不出现 |
\+ | 匹配 1 次或多次 | 在 BRE 中需要使用转义符 \ 匹配前面表达式的至少一个搜索项 匹配尽可能多的次数,如果实在无法匹配,也不要紧 |
\{min,max\} | 量词区间 | 在 BRE 中需要使用转义符 \ |
\| | 或(多选结构) | 在 BRE 中需要使用转义符 \ bob\|nick 能够同时匹配其中任意一个的正则表达式,此时的子表达式被称为 "多选分支" 多选结构可以包括很多字符,但不能超越括号的界限 |
\(\) | 分组 | 在 BRE 中需要使用转义符 \ 括号能够 "记住" 它们包含的子表达式匹配的文本 反向引用(backreference)是正则表达式的特性之一,它允许我们匹配与表达式先前部分匹配的同样的文本 |
\<\> | 单词分界符 | 在 BRE 中需要使用转义符 \ < 和 > 本身并不是源字符,只有它们与反斜线结合时才具有单词分界符的含义 |
\ | 转义符 | 如果需要匹配的某个字符本身就是元字符,就需要使用转义符 |
命名的字符类 | 命名的预定义字符类 | [[:upper:]] [A-Z] [[:lower:]] [a-z] [[:digit:]] [0-9] [[:alnum:]] [0-9a-zA-Z] [[:space:]] 空格或 tab [[:alpha:]] [a-zA-Z] |
[vagrant@localhost tasks]$ echo "aaaaabbbb" | grep "a{5}" //{ 和 }需要转义,否则不起作用,而是被当作普通的字符串 [vagrant@localhost tasks]$ echo "aaaaabbbb" | grep a\{5\} //包含特殊字符时如果不加引号,不起作用 [vagrant@localhost tasks]$ echo "aaaaabbbb" | grep "a\{5\}" //经过转义和使用双引号后,正常输出 aaaaabbbb
[vagrant@localhost tasks]$ echo "a{5}aaaabbbb" | grep a\{5\} // { 和 }不转义就会被当作普通的字符串
a{5}aaaabbbb
常见用例
text1.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | text1 aaaaaa aaa bbbbbb ccccccc dddddd AAAAAA AAA aaabbb AAABBB aaabbb aaa bbb AAA bbb ccc text1 |
text2.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | text2 aaaaaa aaa bbbbbb ccccccc dddddd AAAAAA AAA aaabbb AAABBB aaabbb aaa bbb AAA bbb ccc text2 |
1.搜索指定的单个文件中包含匹配模式的字符串的行
[vagrant@localhost tasks]$ grep "aaa" text1.txt //只搜索一个文件时,只输出匹配行,不输出文件名 aaaaaa aaa aaabbb aaabbb aaa bbb
2.搜索指定的多个文件中包含匹配模式的字符串的行
[vagrant@localhost tasks]$ grep "aaa" text1.txt text2.txt //搜索多个文件时,会在输出的匹配行内容前,同时输出文件名 text1.txt:aaaaaa text1.txt:aaa text1.txt:aaabbb text1.txt:aaabbb text1.txt:aaa bbb text2.txt:aaaaaa text2.txt:aaa text2.txt:aaabbb text2.txt:aaabbb text2.txt:aaa bbb
3.搜索指定的目录中所有文件中包含匹配模式的字符串的行
[vagrant@localhost tasks]$ grep "aaa" ./* //此处通配符*不可缺少,否则不起作用,如4例所示 grep: ./logs: Is a directory ./text1.txt:aaaaaa ./text1.txt:aaa ./text1.txt:aaabbb ./text1.txt:aaabbb ./text1.txt:aaa bbb ./text2.txt:aaaaaa ./text2.txt:aaa ./text2.txt:aaabbb ./text2.txt:aaabbb ./text2.txt:aaa bbb
4.递归目录中的所有文件
注意:默认情况下不能直接搜索目录,要想搜索某个目录中的所有文件,可以在目录后面加上通配符*,就如上面3的例子。如果向搜索指定目录中的所有文件,包括子目录中的文件,那么就需要选项 -R, -r, --recursive
如果我们只想查看匹配到的内容所在文件的名称,可以同时使用 r 和 -l
在递归的过程中排除某些目录,使用选项 --exclude-dir(注意,这里设置的也是正则表达式)
$ grep -r --exclude-dir='.git' 'email' $ grep -r --exclude-dir={.git,xgit} 'email'
在递归的过程中排除指定的文件,使用选项 --exclude
$ grep -r --exclude=*.txt 'email' .
[vagrant@localhost tasks]$ grep "aaa" ./ //只指定目录,默认不起作用 grep: ./: Is a directory [vagrant@localhost tasks]$ grep -r "aaa" ./ //使用选项-r,递归遍历所有目录中的文件,包括子目录中的文件 ./text1.txt:aaaaaa ./text1.txt:aaa ./text1.txt:aaabbb ./text1.txt:aaabbb ./text1.txt:aaa bbb ./text2.txt:aaaaaa ./text2.txt:aaa ./text2.txt:aaabbb ./text2.txt:aaabbb ./text2.txt:aaa bbb
[vagrant@localhost tasks]$ grep -rl "aaa" ./ //只想查看匹配到的内容所在文件的名称,使用选项-l
./text1.txt
./text2.txt
5.输出匹配行内容的同时,输出行号
[vagrant@localhost tasks]$ grep -n "aaa" text1.txt 2:aaaaaa 3:aaa 9:aaabbb 11:aaabbb 12:aaa bbb
6.搜索时忽略大小写,使用选项-i
[vagrant@localhost tasks]$ grep -i "aaa" text1.txt aaaaaa aaa AAAAAA AAA aaabbb AAABBB aaabbb aaa bbb AAA bbb ccc
7.前面说过,grep会默认输出包含匹配模式的字符串的整行,如果只想输出匹配的字符串而不输出整行,使用选项-o
[vagrant@localhost tasks]$ grep -o "aaa" text1.txt //只输出匹配的字符串而不输出整行 aaa aaa aaa aaa aaa aaa
8.当要搜索的内容包含特殊字符时(如正则中的通配符),需要转义\或者选项-F
[vagrant@localhost tasks]$ (echo aaa; echo ".*"; echo bbb)|grep ".*" //".*"在正则中表示任意长度的字符串,所以全部输出,要想只输出".*",需要\对特殊字符进行转义或者-F选项 aaa .* bbb [vagrant@localhost tasks]$ (echo aaa; echo ".*"; echo bbb)|grep "\.\*" //使用\对特殊字符进行转义 .* [vagrant@localhost tasks]$ (echo aaa; echo ".*"; echo bbb)|grep -F ".*" //使用选项-F,把指定的条件会被当成一个字符串来匹配,而不是当作正则表达式 .*
9.统计匹配到的行的数量
[vagrant@localhost tasks]$ grep "aaa" text1.txt aaaaaa aaa aaabbb aaabbb aaa bbb [vagrant@localhost tasks]$ grep -c "aaa" text1.txt //使用选项-c后,不输出匹配的行内容,而是输出匹配行的行数统计 5
10.反转匹配条件
[vagrant@localhost tasks]$ grep -v "aaa" text1.txt //使用选项-v,不输出匹配的行内容,而是输出所有不匹配的行 text1 bbbbbb ccccccc dddddd AAAAAA AAA AAABBB AAA bbb ccc text1
11.从文件中读取正则表达式
如果正则表达式太长,或者是需要指定多个正则表达式,可以把它们放在文件中,然后使用 选项 -f FILE, --file=FILE 来指定这个文件。如果指定了多个正则表达式(每行一个),任何一个匹配到的结果都会被输出:
正则表达式文件pattern.txt,注意,文件中的正则表达式不能加引号,而且换行符要使用unix换行符
text1 a\{3\} ccc
[vagrant@localhost tasks]$ grep -f pattern.txt text1.txt //pattern.txt文件中的所有匹配模式的匹配行都输出
text1
aaaaaa
aaa
ccccccc
aaabbb
aaabbb
aaa bbb
AAA bbb ccc
text1
12.只匹配完整的行
如果我们只对一个完整的行感兴趣,可以使用选项 -x, --line-regexp。这样会忽略那些包含在行中的内容:
[vagrant@localhost tasks]$ grep "aaa" text1.txt aaaaaa aaa aaabbb aaabbb aaa bbb [vagrant@localhost tasks]$ grep -x "aaa" text1.txt //使用选项-x后,只有整行匹配时才会输出,如果匹配内容只是行内的一部分则不会输出 aaa
13.只匹配完整的单词(即匹配内容前后没有其他非空白字符),使用-w。-x为整行匹配,而-w为单词匹配
[vagrant@localhost tasks]$ grep -w "aaa" text1.txt //aaaaaa和aaabbb之类的没有输出,只输出了匹配内容前后没有其他非空白字符的行 aaa aaa bbb
grep还有很多其他的选项,这里就不一一举例了,可以通过 grep --help来查看
[vagrant@localhost tasks]$ grep --help Usage: grep [OPTION]... PATTERN [FILE]... Search for PATTERN in each FILE or standard input. PATTERN is, by default, a basic regular expression (BRE). Example: grep -i 'hello world' menu.h main.c Regexp selection and interpretation: -E, --extended-regexp PATTERN is an extended regular expression (ERE) -F, --fixed-strings PATTERN is a set of newline-separated fixed strings -G, --basic-regexp PATTERN is a basic regular expression (BRE) -P, --perl-regexp PATTERN is a Perl regular expression -e, --regexp=PATTERN use PATTERN for matching -f, --file=FILE obtain PATTERN from FILE -i, --ignore-case ignore case distinctions -w, --word-regexp force PATTERN to match only whole words -x, --line-regexp force PATTERN to 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 matches -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 the file name for each match -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 the part of a line matching PATTERN -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=FILE_PATTERN search only files that match FILE_PATTERN --exclude=FILE_PATTERN skip files and directories matching FILE_PATTERN --exclude-from=FILE skip files matching any file pattern from FILE --exclude-dir=PATTERN directories that match PATTERN will be skipped. -L, --files-without-match print only names of FILEs containing no match -l, --files-with-matches print only names of FILEs containing matches -c, --count print only a count of matching 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) -u, --unix-byte-offsets report offsets as if CRs were not there (MSDOS/Windows) 'egrep' means 'grep -E'. 'fgrep' means 'grep -F'. Direct invocation as either 'egrep' or 'fgrep' is deprecated. When FILE is -, read standard input. With no FILE, read . if a command-line -r is given, - otherwise. If fewer than two FILEs are given, 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: <http://www.gnu.org/gethelp/>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)