Linux日志处理三剑客之基础篇:(基础正则+扩展正则)

Linux 日志处理三剑客前置基础:特殊符号与正则表达式

Linux 日志处理离不开"三剑客":grepsedawk

不过在正式使用它们之前,有两块基础必须先搞清楚:

  • Shell 特殊符号:比如引号、$、反引号、重定向、通配符。
  • 正则表达式:比如 ^$.[]*+?|(){}

这两块如果没分清,后面写日志过滤命令时就很容易出现"看起来对,结果不对"的情况。

比如:

bash 复制代码
grep '.' test.txt
grep '\.' test.txt

这两条命令只差一个反斜杠,但含义完全不同:

  • . 在正则里表示任意单个字符。
  • \. 才表示真正的点号。

所以这篇先把日志处理前置基础整理清楚,后面再看 grepsedawk 会顺很多。

一、Linux 特殊符号

Linux 命令行里很多符号不是普通字符,它们会被 Shell 提前解析。

常见的有:

  • 引号:控制内容是否被解析。
  • $:引用变量。
  • 反引号和 $():执行命令替换。
  • 重定向:改变输入、输出、错误输出的方向。
  • 通配符:匹配文件名。
  • 大括号:批量展开内容。

1. 引号

引号最常见,但也最容易混。

单引号和双引号
符号 作用
' ' 单引号,内容原样输出,不进行变量替换或命令替换
" " 双引号,保留大部分普通字符,但允许变量替换和命令替换

示例:

bash 复制代码
# 测试 echo 'Hello $USER' 和 echo "Hello $USER"
[root@atguigu ~]# echo 'Hello $USER'
Hello $USER

[root@atguigu ~]# echo "Hello $USER"
Hello root

这里的区别很明显:

  • 单引号里的 $USER 被当成普通字符串。
  • 双引号里的 $USER 会被解析成当前用户。

所以如果希望命令里的内容"别乱动,原样输出",优先用单引号;如果希望变量能生效,就用双引号。

2. 美元符号

$ 用来引用变量的值。

常见示例:

bash 复制代码
[root@atguigu ~]# echo $USER
root

[root@atguigu ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

这里:

  • $USER 表示当前用户。
  • $PATH 表示命令搜索路径。

后面写脚本、写日志处理命令时,经常会遇到 $1$2$NF 这类写法。它们在不同工具里含义不完全一样,比如 Shell 脚本里 $1 表示第一个参数,awk$1 表示第一列。

3. 反引号

反引号用于命令替换,也就是把命令执行结果放到当前位置。

除了反引号,也可以使用 $()。实际写脚本时,更推荐 $(),因为它更清晰,也更适合嵌套。

示例:

bash 复制代码
# 测试 echo '`hostname` ybc $(whoami) $USER {1..5}'
[root@atguigu ~]# echo '`hostname` ybc $(whoami) $USER {1..5}'
`hostname` ybc $(whoami) $USER {1..5}

# 测试 echo "`hostname` ybc $(whoami) $USER {1..5}"
[root@atguigu ~]# echo "`hostname` ybc $(whoami) $USER {1..5}"
atguigu ybc root root {1..5}

# 测试 echo `hostname` ybc $(whoami) $USER {1..5}
[root@atguigu ~]# echo `hostname` ybc $(whoami) $USER {1..5}
atguigu ybc root root 1 2 3 4 5

这 3 条命令可以看出几个细节:

  • 单引号内所有内容都不解析。
  • 双引号内会解析变量和命令替换,但 {1..5} 不会展开。
  • 不加引号时,变量、命令替换、大括号展开都会生效。

二、重定向符号

Linux 系统里,输入输出本质上都可以看成"文件流"。

常见的 3 个标准文件描述符:

编号 名称 默认设备 说明
0 STDIN 标准输入 键盘 命令读取输入数据
1 STDOUT 标准输出 显示器 命令执行成功后的正常输出
2 STDERR 标准错误 显示器 命令执行失败时的错误输出

重定向就是改变这些流的方向。

1. 输出重定向

覆盖输出:>

> 等价于 1>,表示把标准输出写入文件。如果文件不存在就创建;如果文件存在就覆盖。

bash 复制代码
# 将 hello,world 输出到 test.txt
[root@atguigu ~]# echo 'hello,world' > test.txt

[root@atguigu ~]# ll
总用量 8
-rw-------. 1 root root 1289 7月   1 10:36 anaconda-ks.cfg
-rw-r--r--. 1 root root   11 7月   1 15:17 test.txt

[root@atguigu ~]# cat test.txt
hello,world

注意:> 会覆盖原文件内容,生产环境里操作日志、配置文件时要特别小心。

追加输出:>>

>> 等价于 1>>,表示追加写入,不覆盖原内容。

bash 复制代码
# 将 hello,linux 追加到 test.txt
[root@atguigu ~]# echo 'hello,linux' >> test.txt

[root@atguigu ~]# cat test.txt
hello,world
hello,linux

日志记录常用 >>,因为通常希望新内容追加到文件末尾,而不是把历史内容覆盖掉。

2. 输入重定向

输入重定向:<

< 等价于 0<,表示把文件内容作为命令输入。

准备测试文件:

bash 复制代码
[root@atguigu ~]# cat test.txt
3
12
33
21
34
55
43
18

test.txt 作为 sort 的输入:

bash 复制代码
[root@atguigu ~]# sort -n < test.txt
3
12
18
21
33
34
43
55

配合 xargs 分组:

bash 复制代码
[root@atguigu ~]# xargs -n3 < test.txt
3 12 33
21 34 55
43 18

这里的 -n3 表示每 3 个参数分一组。

输入追加重定向:<<

<< 常见于多行输入,一般配合 cat 使用,也经常出现在 Shell 脚本中。

bash 复制代码
# 向 test.txt 输入多行内容,到 EOF 结束
# 也可以这样写:cat << EOF > test.txt
[root@atguigu ~]# cat > test.txt << EOF
> hello
> world
> linux
> good
> EOF

[root@atguigu ~]# cat test.txt
hello
world
linux
good

EOF 不是固定写法,它只是一个结束标记。也可以写成 ENDAAA,只要前后一致即可。

3. 错误重定向

覆盖错误输出:2>

2> 表示只把错误输出写入文件。

先看错误命令使用 > 的情况:

bash 复制代码
# 测试1:命令错误,使用 > 或 1> 测试错误信息是否会输出到文件中
[root@atguigu ~]# ech 111 > test.txt
-bash: ech: 未找到命令

[root@atguigu ~]# cat test.txt

因为 > 只接收标准输出,不接收标准错误,所以错误信息仍然显示在屏幕上,文件中没有内容。

再看正确命令使用 2>

bash 复制代码
# 测试2:命令正确,使用 2> 测试输出到文件中的信息是什么
[root@atguigu ~]# echo 111 2> test.txt
111

[root@atguigu ~]# cat test.txt

命令正确时没有错误输出,所以 test.txt 还是空的。

最后看错误命令使用 2>

bash 复制代码
# 测试3:命令错误,使用 2> 测试错误信息是否会输出到文件中
[root@atguigu ~]# ech 111 2> test.txt

[root@atguigu ~]# cat test.txt
-bash: ech: 未找到命令

这次错误信息被写入了文件。

追加错误输出:2>>

2>> 表示把错误输出追加到文件末尾。

bash 复制代码
# 测试追加错误输出
[root@atguigu ~]# ech 111 2>> test.txt

[root@atguigu ~]# cat test.txt
-bash: ech: 未找到命令
-bash: ech: 未找到命令
同时记录标准输出和错误输出

有时不管命令成功还是失败,都希望写入同一个文件。

常见写法:

bash 复制代码
# 方式1:标准输出和错误输出都追加到 test.txt
echo 111 >> test.txt 2>> test.txt

# 方式2:把错误输出合并到标准输出,再追加到 test.txt
echo 111 >> test.txt 2>&1

# 方式3:标准输出和错误输出都追加到 test.txt
echo 111 &>> test.txt

其中 2>&1 的意思是:把 2 号错误输出合并到 1 号标准输出。

三、通配符

通配符主要用于匹配文件名。它是 Shell 层面的功能,不是正则表达式。

1. *?

通配符 含义
* 匹配任意长度的任意字符
? 匹配任意单个字符

示例:

bash 复制代码
# 删除当前目录下的所有 txt 文件
[root@atguigu ~]# rm -f *.txt

# 查询 /etc 目录下,文件名以 p 开头的两个字符的 txt 文件
[root@atguigu ~]# ll /etc/p?.txt

举例说明:

  • *.txt 可以匹配 a.txttest.txtlinux_note.txt
  • p?.txt 可以匹配 pa.txtp1.txt,但不能匹配 passwd.txt

2. 大括号

大括号 {} 用于批量展开一系列值。

bash 复制代码
#{xx,xx,xx} 表示花括号中的每个数据
[root@atguigu ~]# echo atguigu{A,C,X}
atguiguA atguiguC atguiguX

#{开始..结束} 表示从开始到结束的所有数据
[root@atguigu ~]# echo {a..z}
a b c d e f g h i j k l m n o p q r s t u v w x y z

批量创建文件:

bash 复制代码
# 创建 file1.txt、file2.txt、file3.txt
[root@atguigu ~]# touch file{1,2,3}.txt

# 创建 file1.txt 到 file10.txt
[root@atguigu ~]# touch file{1..10}.txt

指定步长:

bash 复制代码
# seq 命令:生成一系列数字,seq 开始 增量 结束
[root@atguigu ~]# seq 1 2 10
1
3
5
7
9

# 使用 {} 实现类似功能,{开始..结束..增量}
[root@atguigu ~]# echo {1..10..2}
1 3 5 7 9

备份文件时也很常用:

bash 复制代码
# 完整写法
[root@atguigu ~]# cp test.txt test.txt.bak

# 使用 {} 简写
[root@atguigu ~]# cp test.txt{,.bak}

test.txt{,.bak} 会展开成:

bash 复制代码
test.txt test.txt.bak

所以整条命令等价于:

bash 复制代码
cp test.txt test.txt.bak

四、正则表达式

正则表达式,英文是 Regular Expression,简称 regex

它的作用是定义一种"匹配规则",用来匹配字符串中的字符组合。

在 Linux 日志处理中,正则主要用于:

  • 匹配某类日志行
  • 查找指定关键字
  • 提取异常信息
  • 删除空行或注释
  • 替换符合规则的内容

1. 正则和通配符的区别

正则和通配符很容易混,但它们不是一回事。

区别 用途 支持的命令
正则 匹配文件内容,也就是匹配字符 grepsedawk、开发语言
通配符 匹配文件名,作为命令参数展开 Linux 大部分命令都支持

简单记:

  • 找文件名,用通配符。
  • 查文件内容,用正则。

例如:

bash 复制代码
ls *.log
grep 'ERROR' app.log

这里:

  • *.log 是通配符,匹配日志文件名。
  • ERROR 是正则中的普通字符匹配,匹配文件内容。

2. 正则分类

常见正则分为基础正则和扩展正则。

特性 基础正则表达式 BRE 扩展正则表达式 ERE
元字符 ^$.*[] ?+{}()、`
工具支持 grep 默认、sed 默认、awk 默认 grep -Eegrepsed -rawk

注意:egrep 等价于 grep -E

五、基础正则

三剑客默认支持基础正则。

先准备测试文件:

bash 复制代码
[root@atguigu ~]# cat test.txt
Here is a sample text for you to test regular expressions
In 2023, Alice123 and Bob456@domain.com attended the TechCon789 event

where they discussed topics like AI42, machine learning models, and the 98765th experiment
The code snippet included functions like def process_data_345

and variables such as result_6789

Additionally, they referred to a dataset named dataset_12345.csv
and used a library called lib67890 to handle some complex computations

1. 包含匹配

直接写普通字符,表示匹配包含该字符的行。

bash 复制代码
# 匹配 test.txt 中包含 I 的行
[root@atguigu ~]# grep 'I' test.txt
In 2023, Alice123 and Bob456@domain.com attended the TechCon789 event
where they discussed topics like AI42, machine learning models, and the 98765th experiment

这里匹配的是包含大写 I 的行。

2. 开始符 ^

^ 表示匹配行首。

bash 复制代码
# 匹配 test.txt 中以 I 开头的行
[root@atguigu ~]# grep '^I' test.txt
In 2023, Alice123 and Bob456@domain.com attended the TechCon789 event

^I 的意思是:这一行必须以 I 开头。

3. 结束符 $

$ 表示匹配行尾。

bash 复制代码
# 匹配 test.txt 中以 t 结尾的行
[root@atguigu ~]# grep 't$' test.txt
In 2023, Alice123 and Bob456@domain.com attended the TechCon789 event
where they discussed topics like AI42, machine learning models, and the 98765th experiment

如果结果看着不符合预期,可以使用 cat -A 文件 查看隐藏字符,比如行尾是否有空格、回车等。

4. 同时使用行首和行尾

^I$ 表示只匹配一整行只有 I 的行。

bash 复制代码
# "^I$" 匹配只有 I 的行
[root@atguigu ~]# grep '^I$' test.txt

没有匹配结果,因为文件中没有单独一行 I

追加一行:

bash 复制代码
[root@atguigu ~]# echo I >> test.txt

[root@atguigu ~]# grep '^I$' test.txt
I

^$ 表示匹配空行。

bash 复制代码
# 匹配 test.txt 中的空行并展示行号
[root@atguigu ~]# grep -n '^$' test.txt
3:
6:
8:

排查配置文件时,^$ 很常用,可以用来过滤空行。

5. 符号 .

. 表示匹配任意单个字符,空行除外。

bash 复制代码
# 匹配 test.txt 中包含 "an." 的行
[root@atguigu ~]# grep 'an.' test.txt
In 2023, Alice123 and Bob456@domain.com attended the TechCon789 event
where they discussed topics like AI42, machine learning models, and the 98765th experiment
and variables such as result_6789
and used a library called lib67890 to handle some complex computations

-o 可以只显示匹配到的内容:

bash 复制代码
[root@atguigu ~]# grep -o 'an.' test.txt
and
and
and
and
and

这里 an. 可以匹配 and,因为 . 匹配了 d

6. 转义符 \

如果要匹配特殊符号本身,需要使用反斜杠转义。

例如,如何匹配包含点号 . 的行?

下面这种写法不准确:

bash 复制代码
grep '.' test.txt

因为 . 在正则里表示任意单个字符,不是点号本身。

实际效果:

bash 复制代码
[root@atguigu ~]# grep '.' test.txt
Here is a sample text for you to test regular expressions
In 2023, Alice123 and Bob456@domain.com attended the TechCon789 event
where they discussed topics like AI42, machine learning models, and the 98765th experiment
The code snippet included functions like def process_data_345
and variables such as result_6789
Additionally, they referred to a dataset named dataset_12345.csv
and used a library called lib67890 to handle some complex computations
I

正确写法:

bash 复制代码
[root@atguigu ~]# grep '\.' test.txt
In 2023, Alice123 and Bob456@domain.com attended the TechCon789 event
Additionally, they referred to a dataset named dataset_12345.csv

\. 表示匹配真正的点号。

7. 字符集合 []

[] 表示匹配括号中出现的任意一个字符。

比如:

  • [123] 表示匹配 123
  • [0-9] 表示匹配任意数字。
  • [a-z] 表示匹配任意小写字母。
  • [A-Z] 表示匹配任意大写字母。
  • [a-zA-Z] 表示匹配任意字母。
  • [0-9a-zA-Z_] 表示匹配任意字母、数字、下划线。

示例:

bash 复制代码
# 匹配 test.txt 中包含 0 或 1 或 2 的行
[root@atguigu ~]# grep '[012]' test.txt
In 2023, Alice123 and Bob456@domain.com attended the TechCon789 event
where they discussed topics like AI42, machine learning models, and the 98765th experiment
Additionally, they referred to a dataset named dataset_12345.csv
and used a library called lib67890 to handle some complex computations

注意:[012] 匹配的是单个字符 012,不是匹配 012 这个整体。

使用 -o 看得更清楚:

bash 复制代码
[root@atguigu ~]# grep -o '[0-2]' test.txt
2
0
2
1
2
2
1
2
0

还有几个常见写法:

bash 复制代码
# 匹配以 I 或 A 开头的行
grep '^[AI]' test.txt

# 匹配包含 . 或 ! 或空格的行
grep '[.! ]' test.txt

[] 中,很多特殊字符会失去特殊含义。比如 [.] 可以匹配点号。

8. and[and] 的区别

这个点很重要。

bash 复制代码
grep 'and' test.txt
grep '[and]' test.txt

它们含义不一样:

  • and:匹配连续的字符串 and
  • [and]:匹配 and 中任意一个字符。

所以 [and] 匹配范围更宽,只要行里有 and,就会匹配。

9. 排除集合 [^]

[^abc] 表示匹配除了 abc 以外的任意字符。

bash 复制代码
#[abc] 表示匹配 a 或 b 或 c
#[^abc] 表示匹配除 a、b、c 以外的字符
[root@atguigu ~]# grep '[^abc]' test.txt
Here is a sample text for you to test regular expressions
In 2023, Alice123 and Bob456@domain.com attended the TechCon789 event
where they discussed topics like AI42, machine learning models, and the 98765th experiment
The code snippet included functions like def process_data_345
and variables such as result_6789
Additionally, they referred to a dataset named dataset_12345.csv
and used a library called lib67890 to handle some complex computations
I

这个结果可能看起来有点怪:为什么几乎都匹配到了?

原因是只要一行里存在任意一个"不是 a/b/c 的字符",整行就会被匹配。大部分文本行都符合这个条件。

10. 匹配任意次 *

* 表示前一个字符可以出现任意次,包括 0 次。

bash 复制代码
# * 在字符后使用,表示匹配的字符可以出现任意次,即 0 次或 0 次以上
# 例如:[abc]* 表示匹配任意次数的 a 或 b 或 c
[root@atguigu ~]# grep '[abc]*' test.txt
Here is a sample text for you to test regular expressions
In 2023, Alice123 and Bob456@domain.com attended the TechCon789 event

where they discussed topics like AI42, machine learning models, and the 98765th experiment
The code snippet included functions like def process_data_345

and variables such as result_6789

Additionally, they referred to a dataset named dataset_12345.csv
and used a library called lib67890 to handle some complex computations
I

最后一行 I 并没有出现 abc,但也匹配到了。

原因是 * 允许前面的内容出现 0 次。

11. 所有字符 .*

. 表示任意单个字符,* 表示前一个字符任意次。

组合起来:

bash 复制代码
.*

就表示匹配任意内容。

这是日志处理中非常常用的写法,比如:

bash 复制代码
grep 'ERROR.*timeout' app.log

含义是:匹配包含 ERROR,并且后面某个位置还有 timeout 的行。

六、扩展正则

三剑客支持扩展正则的方式:

工具 扩展正则方式
grep 使用 -E,即 grep -E
egrep 等价于 grep -E
sed 使用 -r
awk 默认支持

1. 匹配至少一次 +

+ 表示前一个字符至少出现 1 次。

例如 [0-9]+ 表示连续出现的数字。

直接用普通 grep

bash 复制代码
# 匹配 test.txt 中连续出现数字的行
[root@atguigu ~]# grep '[0-9]+' test.txt

没有结果,因为 grep 默认不支持扩展正则里的 +

使用 egrep

bash 复制代码
[root@atguigu ~]# egrep -o '[0-9]+' test.txt
2023
123
456
789
42
98765
345
6789
12345
67890

也可以写成:

bash 复制代码
grep -E -o '[0-9]+' test.txt

2. 匹配 0 次或 1 次 ?

? 表示前一个字符出现 0 次或 1 次。

准备测试文件:

bash 复制代码
[root@atguigu ~]# cat message.txt
I am cool.
I am col.
I am cl.

先看 *

bash 复制代码
# co*l:o 可以出现 0 次或多次
[root@atguigu ~]# egrep 'co*l' message.txt
[root@atguigu ~]# egrep 'co{0,}l' message.txt
I am cool.
I am col.
I am cl.

再看 +

bash 复制代码
# co+l:o 至少出现 1 次
[root@atguigu ~]# egrep 'co+l' message.txt
[root@atguigu ~]# egrep 'co{1,}l' message.txt
I am cool.
I am col.

最后看 ?

bash 复制代码
# co?l:o 出现 0 次或 1 次
[root@atguigu ~]# egrep 'co?l' message.txt
[root@atguigu ~]# egrep 'co{0,1}l' message.txt
I am col.
I am cl.

这几个写法可以这样记:

写法 含义 能匹配
co*l o 出现 0 次或多次 clcolcool
co+l o 至少出现 1 次 colcool
co?l o 出现 0 次或 1 次 clcol

3. 或者 |

| 表示"或者"。

如果只是单个字符的"或",可以用 [];如果是字符串整体的"或",就用 |

示例:匹配包含 Inand 的行。

bash 复制代码
[root@atguigu ~]# egrep 'In|and' test.txt
In 2023, Alice123 and Bob456@domain.com attended the TechCon789 event
where they discussed topics like AI42, machine learning models, and the 98765th experiment
and variables such as result_6789
and used a library called lib67890 to handle some complex computations

4. 排除空行和注释

排查配置文件时,经常需要排除空行和注释。

比如 /etc/ssh/sshd_config 中,很多行是空行或 # 开头的注释。

方式一:先排除空行,再排除注释。

bash 复制代码
# 错误结果
[root@atguigu ~]# egrep -nv '^$' /etc/ssh/sshd_config | grep -v '^#'

这条命令的问题是:egrep -n 会在输出前加行号,比如:

bash 复制代码
12:#PermitRootLogin yes

此时这一行已经不是以 # 开头了,而是以行号 12: 开头,所以 grep -v '^#' 排不掉它。

正确写法:

bash 复制代码
[root@atguigu ~]# egrep -nv '^$' /etc/ssh/sshd_config | egrep -v '#'

方式二:直接用扩展正则一次排除空行和注释。

bash 复制代码
[root@atguigu ~]# egrep -nv '^$|^#' /etc/ssh/sshd_config

这里:

  • ^$ 表示空行。
  • ^# 表示以 # 开头的注释行。
  • | 表示或者。

5. 小括号 ()

小括号用于把内容作为一个整体。

示例:查看软件安装列表,并过滤出以 treevim 开头的软件。

bash 复制代码
[root@atguigu ~]# rpm -qa | egrep '^tree|^vim'
[root@atguigu ~]# rpm -qa | egrep '^(tree|vim)'

第二种写法更清晰:

bash 复制代码
^(tree|vim)

含义是:以 treevim 开头。

如果不加括号,^tree|^vim 也能实现类似效果,但当表达式复杂后,可读性会变差。

6. 花括号 {}

{} 用于指定前一个字符出现的次数。

写法 含义
{x} 必须出现 x 次
{x,y} 出现 x 到 y 次
{x,} 至少出现 x 次
{,y} 最多出现 y 次

示例:查询 test.txt 中连续出现 5 个数字的行。

bash 复制代码
[root@atguigu ~]# egrep '[0-9]{5}' test.txt
where they discussed topics like AI42, machine learning models, and the 98765th experiment
Additionally, they referred to a dataset named dataset_12345.csv
and used a library called lib67890 to handle some complex computations

7. 匹配身份证号和手机号

准备测试文件:

bash 复制代码
[root@atguigu ~]# cat student.txt
张三 370102198705123456    #姓名 身份证号
李四 420901199008234567
王五 23010419761130123X
赵六 510105198504056789
孙七 320311199207182345
周八 13400134000    #姓名 手机号
吴九 13300133000
郑十 13200132000
钱伯 13100131000
孔仲 13000130000

匹配身份证号:

bash 复制代码
# 身份证号的正则表达式:[1-9][0-9]{16}[0-9X]
[root@atguigu ~]# egrep '[1-9][0-9]{16}[0-9X]$' student.txt
张三 370102198705123456
李四 420901199008234567
王五 230104197611301234
赵六 510105198504056789
孙七 320311199207182345

这里的规则拆开看:

  • [1-9]:第一位不能是 0。
  • [0-9]{16}:中间 16 位数字。
  • [0-9X]:最后一位可以是数字或 X
  • $:必须以身份证号结尾。

匹配手机号:

bash 复制代码
# 手机号的正则表达式:1[356789][0-9]{9}
[root@atguigu ~]# egrep '1[356789][0-9]{9}$' student.txt
周八 13400134000
吴九 13300133000
郑十 13200132000
钱伯 13100131000
孔仲 13000130000

规则拆开看:

  • 1:手机号以 1 开头。
  • [356789]:第二位匹配 3、5、6、7、8、9。
  • [0-9]{9}:后面 9 位数字。
  • $:必须以手机号结尾。

七、常见易错点

1. 通配符和正则不要混用

bash 复制代码
ls *.log
grep '.*ERROR.*' app.log

第一条里的 * 是通配符,用来匹配文件名。

第二条里的 .* 是正则,用来匹配文件内容。

2. . 默认不是点号

bash 复制代码
grep '.' test.txt
grep '\.' test.txt
  • . 表示任意单个字符。
  • \. 表示真正的点号。

3. * 表示 0 次或多次

bash 复制代码
grep '[abc]*' test.txt

因为 * 允许出现 0 次,所以它很容易匹配出比预期更多的内容。

4. grep 默认不支持扩展正则

bash 复制代码
grep '[0-9]+' test.txt
grep -E '[0-9]+' test.txt
egrep '[0-9]+' test.txt

如果要用 +?|(){} 这类扩展正则,建议直接使用:

bash 复制代码
grep -E

或者:

bash 复制代码
egrep

5. 带行号后再过滤注释要注意

bash 复制代码
egrep -nv '^$' /etc/ssh/sshd_config | grep -v '^#'

这条容易失效,因为 -n 加了行号后,注释行不再以 # 开头。

更直接的写法:

bash 复制代码
egrep -nv '^$|^#' /etc/ssh/sshd_config

八、常用速查总结

1. 特殊符号速查

符号 含义
' ' 单引号,内容原样输出
" " 双引号,允许变量和命令替换
$ 引用变量
cmd 命令替换
$(cmd) 命令替换,推荐写法
> 覆盖标准输出
>> 追加标准输出
< 文件作为标准输入
<< 多行输入
2> 覆盖错误输出
2>> 追加错误输出
2>&1 错误输出合并到标准输出
* 通配符,匹配任意长度文件名
? 通配符,匹配单个字符
{} 批量展开

2. 基础正则速查

正则 含义
abc 匹配包含 abc 的行
^abc 匹配以 abc 开头的行
abc$ 匹配以 abc 结尾的行
^$ 匹配空行
. 任意单个字符
\. 匹配点号
[abc] 匹配 abc 任意一个
[^abc] 匹配非 abc 的字符
[0-9] 匹配任意数字
[a-z] 匹配任意小写字母
* 前一个字符出现 0 次或多次
.* 匹配任意内容

3. 扩展正则速查

正则 含义
+ 前一个字符至少出现 1 次
? 前一个字符出现 0 次或 1 次
` `
() 分组,把内容作为整体
{x} 出现 x 次
{x,y} 出现 x 到 y 次
{x,} 至少出现 x 次
{,y} 最多出现 y 次

4. 常用命令组合

bash 复制代码
# 查看非空、非注释配置
egrep -nv '^$|^#' /etc/ssh/sshd_config

# 匹配连续数字
egrep -o '[0-9]+' test.txt

# 匹配空行并显示行号
grep -n '^$' test.txt

# 匹配包含真正点号的行
grep '\.' test.txt

# 标准输出和错误输出都追加到日志
command >> run.log 2>&1

# 另一种写法
command &>> run.log

最后记住一句话:

通配符处理文件名,正则处理文件内容;基础正则默认可用,扩展正则要看工具参数。

这个边界分清楚后,后面再写日志过滤、文本替换、字段统计,命令就不容易乱。

相关推荐
暗影凋落1 小时前
docker-image 工具展示更详细镜像层内容
运维·docker·容器
深圳市爱派派智能科技有限公司2 小时前
“进迭时空 RISC-V 集群服务器 CSB1-N10SPK3:10 节点 K3,600 TOPS 绿色算力“
运维·服务器·risc-v·k3·进迭时空·集群服务器
☆凡尘清心☆2 小时前
Linux运维故障排查速查命令清单
linux·运维·服务器
QWEDDRFTG2 小时前
机房供电安全
服务器
极客先躯2 小时前
高级java每日一道面试题-2026年05月11日-实战篇[Docker]-如何容器化金融产品推荐系统?
java·运维·docker·容器·金融·高级面试·金融产品推荐系统
小泊客2 小时前
友善R5C刷OpenWrt后RTL8822CE无线网卡显示“禁用”或“未激活”的完整解决方案
linux·github·运维开发
nvd112 小时前
GCP L4 Passthrough 负载均衡器“假死超时”深度排查复盘
运维·php·负载均衡
mounter6252 小时前
跨内核实时更新:如何实现 hugetlbfs 巨页的无缝保留与恢复?
linux·linux kernel·kernel·kexec·liveupdate·kho
qeen872 小时前
【Linux】make/Makefile 自动化工具的介绍
linux·运维·服务器·自动化