grep
Grep 是一个命令行工具,用于在文本文件中搜索打印匹配指定模式的行。它的名称来自于 “Global Regular Expression Print”(全局正则表达式打印),它最初是由 Unix 系统上的一种工具实现的。Grep 工具在 Linux 和其他类 Unix 系统中广泛使用,它提供了强大的文本搜索功能。
基本格式
grep [option] pattern [file…]
grep命令的匹配模式pattern带"“、不带”"和’'的区别如下
- 不带引号(直接写模式)
Shell 会对模式中的特殊字符(如 *、?、$、空格等)进行解释(比如展开通配符或变量)。
如果模式中包含空格或特殊字符,可能会导致 grep 接收错误的参数。
示例:
grep hello world file # 错误!Shell 会认为 `hello` 和 `world` 是两个参数。
grep hello*world file # 如果当前目录有匹配 `hello*world` 的文件,Shell 会先进行文件名扩展。
- 双引号 “”
bash
grep “pattern” file
Shell 会解释双引号内的变量($VAR)和命令替换(command
或 $(command)),但其他字符(如 *、?)会被保留。
适合模式中包含空格或需要保留部分特殊字符(如 $ 用于正则表达式)时使用。
示例:
grep "hello world" file # 正确匹配包含 "hello world" 的行。
grep "$USER" file # Shell 会替换 `$USER` 为当前用户名,然后传递给 grep。
grep "*.txt" file # `*` 不会被 Shell 扩展,而是作为正则表达式传递给 grep。
- 单引号 ‘’
Shell 不会对单引号内的任何字符(包括变量和通配符)进行解释,所有内容会原样传递给 grep。适合模式中包含需要保留的 $、* 等正则表达式元字符时使用。
示例:
grep 'pattern' file
grep '$USER' file # 直接匹配字符串 `$USER`(而非变量值)。
grep 'hello*world' file # `*` 作为正则表达式的量词(匹配 0 或多个 `o`)。
grep 'a b' file # 匹配包含 "a b" 的行。
正则表达式
在 Linux 中,正则表达式(Regular Expressions, regex)用于文本匹配和处理,常见的工具如 grep、sed、awk 等都支持正则表达式。正则表达式由 元字符(metacharacters) 和 普通文字(literal characters) 组成:
- 普通文字(Literal Characters)
普通文字就是字面意义上的字符,例如 a、1、- 等,它们匹配自身:
grep "hello" file.txt # 匹配包含 "hello" 的行
h、e、l、l、o 都是普通文字,直接匹配。
- 元字符(Metacharacters)
元字符在正则表达式中有特殊含义,用于匹配模式。常见的元字符包括:
元字符 | 描述 | 示例 |
---|---|---|
. | 匹配 任意单个字符(除换行符 \n) | a.c 匹配 abc、a1c、a-c |
^ | 匹配 行首 | ^hello 匹配以 hello 开头的行 |
$ | 匹配 行尾 | world$ 匹配以 world 结尾的行 |
* | 匹配前一个字符 0 次或多次 | go*d 匹配 gd、god、good |
+ | 匹配前一个字符 1 次或多次 | (grep -E 或 egrep 支持) go+d 匹配 god、good,但不匹配 gd |
? | 匹配前一个字符 0 次或 1 次 | (grep -E 或 egrep 支持) colou?r 匹配 color 和 colour |
[…] | 匹配 括号内的任意一个字符 | [aeiou] 匹配任意一个元音字母 |
[^…] | 匹配 不在括号内的任意一个字符 | [^0-9] 匹配非数字字符 |
\ | 转义字符,使元字符变为普通字符 | \.匹配 . 而不是任意字符 |
{n} | 匹配前一个字符 恰好 n 次(grep -E 或 egrep 支持) | a{3} 匹配 aaa |
{n,} | 匹配前一个字符 至少 n 次(grep -E 或 egrep 支持) | a{2,} 匹配 aa、aaa、aaaa… |
{n,m} | 匹配前一个字符 n 到 m 次(grep -E 或 egrep 支持) | a{2,4} 匹配 aa、aaa、aaaa |
- 正则表达式模式示例
(1) 基本匹配
grep "hello" file.txt # 匹配包含 "hello" 的行
grep "^hello" file.txt # 匹配以 "hello" 开头的行
grep "world$" file.txt # 匹配以 "world" 结尾的行
grep "h.llo" file.txt # 匹配 "hallo"、"hello"、"hxllo" 等
(2) 字符类 […]
grep "[aeiou]" file.txt # 匹配包含任意元音字母的行
grep "[0-9]" file.txt # 匹配包含数字的行
grep "[^0-9]" file.txt # 匹配包含非数字的行
(3) 量词 *, +, ?, {n,m}
grep "go*d" file.txt # 匹配 "gd", "god", "good", "gooood" 等
grep -E "go+d" file.txt # 匹配 "god", "good", 但不匹配 "gd"
grep -E "colou?r" file.txt # 匹配 "color" 或 "colour"
grep -E "a{3}" file.txt # 匹配 "aaa"
grep -E "a{2,4}" file.txt # 匹配 "aa", "aaa", "aaaa"
(4) 转义字符 \
grep "\.txt" file.txt # 匹配 ".txt"(而不是 "atxt"、"btxt" 等)
grep "\\" file.txt # 匹配反斜杠 `\`(需要双重转义)
(5) 或操作 |
grep -E "cat|dog" file.txt # 匹配 "cat" 或 "dog"
- grep 不同模式的区别
模式 | 命令 | 说明 |
---|---|---|
基本正则表达式(BRE) | grep “pattern” | 默认模式,*、^、$ 等元字符可用,但 +、?、 需要转义 |
扩展正则表达式(ERE) | grep -E 或 egrep | 支持 +、?、{n,m} 等,无需转义 |
固定字符串模式 | grep -F 或 fgrep | 禁用正则表达式,直接匹配文字 |