grep 命令简介
grep 是一个在 Linux/Unix 系统中非常强大和常用的命令行工具,它的全称是 Global Regular Expression Print,即“全局正则表达式打印”。

核心功能: 在指定的文件中搜索匹配特定“模式”(pattern)的行,并将这些行打印到标准输出(通常是你的终端屏幕)上。
这个“模式”可以是一个简单的字符串,也可以是一个复杂的正则表达式。
grep -c 命令详解
grep -c 命令是 grep 的一个常用变体,它的作用不是打印匹配的行本身,而是计算并输出匹配行的总数量。
语法
grep -c [选项] '模式' 文件...
-c或--count: 关键选项,表示计数模式。[选项]: 其他grep选项,-i(忽略大小写),-v(反向匹配) 等。'模式': 你要搜索的字符串或正则表达式。建议用单引号括起来,以防止 shell 误解其中的特殊字符(如 , , 等)。文件...: 一个或多个要搜索的文件名。
工作原理
grep -c 的工作流程如下:

- 读取输入文件(或标准输入)中的每一行。
- 判断该行是否匹配指定的“模式”。
- 如果匹配,则计数器加一。
- 处理完所有行后,只输出最终的计数值,而不是匹配的行内容。
示例
我们首先创建一个示例文件 log.txt,方便后续演示:
cat > log.txt << EOF 2025-10-27 10:00:01 INFO: User 'Alice' logged in. 2025-10-27 10:01:15 ERROR: Disk space is full. 2025-10-27 10:02:30 INFO: User 'Bob' logged in. 2025-10-27 10:03:45 WARN: Connection timeout. 2025-10-27 10:04:50 INFO: User 'Alice' logged in again. 2025-10-27 10:05:00 ERROR: Failed to start service. EOF
示例 1:基本用法
统计 log.txt 文件中包含字符串 "INFO" 的行数。
grep -c 'INFO' log.txt
输出:

3
解释:文件中有 3 行包含 "INFO"。
示例 2:结合 -i 选项(忽略大小写)
统计包含 "error"(不区分大小写)的行数。
grep -ci 'error' log.txt
输出:
2
解释:文件中有 1 行 "ERROR" 和 1 行 "Failed to start service"(如果模式是 error,它不会匹配,但如果模式是 err,则会匹配),为了更准确,我们换个模式。
grep -ci 'err' log.txt
输出:
2
解释:现在它正确匹配了 "ERROR" 和 "Failed to start service"(包含 "err")这两行。
示例 3:结合 -v 选项(反向匹配)
统计不包含 "INFO" 的行数。
grep -vc 'INFO' log.txt
输出:
3
解释:总共有 6 行,3 行包含 "INFO",6 - 3 = 3 行不包含。
示例 4:在多个文件中搜索
假设我们还有一个文件 error.log:
cat > error.log << EOF This is the first error message. This is another ERROR. Everything is fine here. An error occurred. EOF
我们想在 log.txt 和 error.log 中同时搜索 "error"(忽略大小写),并分别输出每个文件中的匹配行数。
grep -c 'error' log.txt error.log
输出:
log.txt:2
error.log:3
解释:grep 会为每个文件输出一个结果,格式为 文件名:计数值。
grep 的其他常用选项
为了让你更好地理解 grep 的强大,这里列出一些其他常用选项,它们可以和 -c 结合使用。
| 选项 | 全称 | 作用 |
|---|---|---|
-i |
--ignore-case |
忽略大小写进行搜索。 |
-v |
--invert-match |
反向选择,即输出不匹配的行。 |
-n |
--line-number |
显示匹配行的行号。 |
-r / -R |
--recursive |
递归地搜索指定目录下的所有文件。 |
-w |
--word-regexp |
只匹配整个单词,而不是字符串的一部分。 |
-l |
--files-with-matches |
只列出包含匹配项的文件名,而不显示匹配的行。 |
-E |
--extended-regexp |
使用扩展的正则表达式。 |
示例:-n 和 -w 的结合
# 查找 log.txt 中以 "User" 开头的行,并显示行号 grep -n '^User' log.txt # 输出: # 1:User 'Alice' # 3:User 'Bob' # 5:User 'Alice' # 查找 log.txt 中独立的单词 "in"(而不是 "in" 作为其他单词的一部分,如 "login") grep -nw 'in' log.txt # 输出: # 1:in. # 3:in. # 5:in.
重要注意事项:grep -c 与 wc -l 的区别
一个常见的初学者错误是使用 grep 'pattern' file | wc -l 来达到和 grep -c 相同的目的,虽然它们在很多情况下结果相同,但存在关键区别。
# 方法1:使用 grep -c grep -c 'INFO' log.txt # 方法2:使用管道和 wc -l grep 'INFO' log.txt | wc -l
区别:
-
性能和效率:
grep -c是一个单一的过程。grep在读取文件时进行计数,最后只输出一个数字,内存和CPU开销很小。grep ... | wc -l涉及两个进程。grep首先找到所有匹配的行,并将它们通过管道传递给wc -l,wc -l再来计算这些行的数量,这个过程需要将所有匹配的行都加载到内存中(或通过管道传递),如果匹配结果非常多,这会消耗更多内存和CPU。
-
行为(尤其是在错误处理上):
grep -c的设计就是只输出计数,如果文件不存在,grep会报错并退出,不会输出任何计数。grep ... | wc -l的行为则不同,如果文件不存在,grep会报错(如grep: log.txt: No such file or directory),然后退出,由于grep没有向wc -l传递任何数据,wc -l会认为输入为空,因此输出0。
如果你只想知道匹配行的数量,请始终使用 grep -c。 它更高效、更直接,并且行为更符合预期(文件不存在时不输出 0)。
| 命令 | 功能 | 输出示例 |
|---|---|---|
grep 'pattern' file |
打印所有匹配的行 | INFO: User 'Alice' logged in. |
grep -c 'pattern' file |
计算并打印匹配行的总数 | 3 |
grep -n 'pattern' file |
打印所有匹配的行及其行号 | 1:INFO: User 'Alice' logged in. |
grep -v 'pattern' file |
打印所有不匹配的行 | ERROR: Disk space is full. |
grep 'pattern' file \| wc -l |
通过管道计算匹配行数(不推荐) | 3 |
grep -c 是 grep 工具箱中一个非常基础且高效的工具,掌握它能让你在日常的系统管理和文本处理工作中事半功倍。
