豁然高

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

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/>
复制代码

 

posted on   豁然高  阅读(411)  评论(0编辑  收藏  举报

编辑推荐:
· 基于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)
点击右上角即可分享
微信分享提示