在 Linux 日常开发与运维中,除了 cd、ls、mkdir 这些基础命令外,我们大部分时间都在与文本和日志打交道。
本文整理了 grep(文本搜索)和 sed(流编辑)在实际工作中的高频使用场景,涵盖日志故障排查、配置修改及数据清洗等操作。
🔍 一、grep 命令:查找与过滤
grep (Global Regular Expression Print) 是最强大的文本搜索工具,常用于日志分析、代码搜索和配置文件过滤。
1. 场景一:故障排查与日志上下文分析
在排查线上故障(如 Java 应用的空指针异常)时,仅仅找到“Error”关键词是不够的,通常需要查看报错前后的堆栈信息。
示例:分析 NullPointerException
查看报错及其后 50 行(定位堆栈)
使用-A(After) 参数可以显示匹配行之后的行,配合less分页查看,体验最佳。1
grep -A 50 "java.lang.NullPointerException" a.log | less
统计报错出现的次数
快速评估故障严重程度,使用-c(Count) 参数。1
grep -c "java.lang.NullPointerException" a.log
动态追踪报错日志
结合tail -f实时监控。
注意:当使用-A上下文参数配合管道流时,输出可能会有缓冲延迟。1
tail -f a.log | grep -A 50 "java.lang.NullPointerException"
2. 场景二:实时监控与关键词过滤
在系统维护中,我们需要从不断滚动的海量日志中,实时“捞”出我们关心的信息。
| 目标 | 命令示例 | 解释 | |
|---|---|---|---|
| 实时过滤包含 “Error” 的行 | `tail -f server.log | grep —line-buffered “Error”` | --line-buffered 确保输出不被缓存,实时显示。 |
| 查找最近 500 行中特定 IP 的请求 | `tail -n 500 access.log | grep “192.168.1.1”` | 组合使用,快速定位最近的访问记录。 |
3. 场景三:代码库与配置文件的快速搜索
在庞大的工程目录或 /etc 配置目录中,快速定位包含特定字符串的文件。
| 目标 | 命令示例 | 解释 |
|---|---|---|
| 递归查找代码中的关键词 | grep -r -n "malloc" *.c |
-r 递归子目录查找,-n 显示行号,*.c 限定文件后缀。 |
| 查看有效的配置项(排除注释) | grep -v "^#" config.conf |
-v 反向匹配,^# 正则匹配以 # 开头的行。常用于过滤掉大量注释。 |
| 精准查找完整单词 | grep -i -w "port" settings.ini |
-i 忽略大小写,-w 强制全词匹配(避免匹配到 “portable” 等词)。 |
✂️ 二、sed 命令:文本替换与结构化修改
sed (Stream Editor) 是非交互式的流编辑器,最常用于批量修改配置文件、数据清洗/格式化和删除特定行。
1. 场景一:批量替换字符串(配置文件修改)
这是 sed 的杀手级功能,特别适合在自动化部署脚本中使用,无需人工打开编辑器即可修改文件。
| 目标 | 命令示例 | 解释 |
|---|---|---|
| 全局替换并保存文件 | sed -i 's/http/https/g' config.ini |
s/旧/新/g 是标准替换语法,g 代表全局替换。-i (in-place) 表示直接修改原文件。 |
| 仅替换特定行范围 | sed '10,20s/user/admin/g' data.txt |
在 s 前添加 10,20,指定仅在第 10 到 20 行之间执行替换。 |
| 删除特定结尾的行 | sed '/;$/d' script.js |
/;$/ 匹配以分号结尾的行,d 指令执行删除操作。 |
2. 场景二:数据清洗和格式重排
利用 sed 的扩展正则表达式和捕获组功能,可以对 CSV 或日志数据进行复杂的格式调整。
| 目标 | 命令示例 | 解释 |
|---|---|---|
| 交换 CSV 列的位置 | sed -E 's/([^,]*),([^,]*),([^,]*)/\3,\2,\1/' file.csv |
-E 启用扩展正则。(...) 是捕获组,\1、\2、\3 分别引用捕获到的第一、二、三个字段,实现列的重排。 |
| 批量添加注释 | sed 's/^/#/' file.txt |
^ 匹配行首,将其替换为 #,从而快速注释掉整个文件的内容。 |
🖥️ 三、系统状态监控:top 与 free
当服务器变慢或负载报警时,首先要看的就是 CPU 和内存。
1. top:实时显示系统资源与进程
top 相当于 Linux 的任务管理器。
- 常用操作:直接输入
top回车。 - 交互快捷键(进入 top 界面后按):
P(大写):按 CPU 使用率排序(找 CPU 飙高的进程)。M(大写):按 内存 使用率排序(找吃内存的进程)。1(数字):展开查看每个逻辑 CPU 核心的负载。q:退出。
2. free:查看内存使用情况
查看服务器剩余内存最直观的命令。
| 目标 | 命令示例 | 解释 |
|---|---|---|
| 以人类可读格式查看(GB/MB) | free -h |
-h (human-readable) 自动转换单位。重点关注 available 列(实际可用内存)。 |
| 每 3 秒刷新一次 | free -h -s 3 |
-s 指定刷新间隔,用于监控内存变化趋势。 |
💾 四、磁盘空间管理:df 与 du
磁盘满了会导致服务挂掉,这两个命令一个看“宏观”,一个看“微观”。
1. df:查看文件系统磁盘占用 (Disk Free)
用于检查整体磁盘分区是否已满。
| 目标 | 命令示例 | 解释 |
|---|---|---|
| 查看磁盘挂载点及使用率 | df -h |
-h 显示易读格式(G/M)。重点看 Use% 和 Mounted on。 |
| 查看 inode 使用情况 | df -i |
有时磁盘空间没满但 inode 满了(小文件过多),也会导致无法写入。 |
2. du:查看文件/目录大小 (Disk Usage)
当 df 显示磁盘满了,用 du 来找出具体是哪个目录在占用空间。
| 目标 | 命令示例 | 解释 | |
|---|---|---|---|
| 查看当前目录下每个子目录的大小 | du -sh * |
-s (summary) 汇总大小,-h 易读格式,* 代表当前目录所有文件。非常高频的命令! |
|
| 深度为 1 的目录下大小排序 | `du -h —max-depth=1 | sort -hr` | 快速定位当前目录下最大的文件夹。 |
🌐 五、网络与进程快照:ps 与 netstat
1. ps:查看进程快照
不同于 top 的实时监控,ps 用于查找特定的进程信息。
| 目标 | 命令示例 | 解释 | |
|---|---|---|---|
| 查找特定服务(如 Java)进程 | `ps -ef \ | grep java` | -ef 显示所有进程的全格式信息。配合 grep 查找 PID。 |
| 查看占用 CPU/内存 最高的 10 个进程 | `ps aux —sort=-%cpu \ | head -11` | aux 显示更详细的用户和资源信息,head -11 显示表头+前10行。 |
2. netstat:网络端口查看
查看服务端口是否启动,或者查看是否存在大量异常连接。
注意:部分新系统可能需要安装 net-tools 或使用 ss 命令替代。
| 目标 | 命令示例 | 解释 | |
|---|---|---|---|
| 查看所有监听中的 TCP/UDP 端口 | netstat -tulpn |
-t (tcp), -u (udp), -l (listening), -p (显示进程名/PID), -n (不解析域名,直接显示IP)。 |
|
| 统计各类连接状态的数量 | `netstat -n \ | awk ‘/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}’` | 高级用法,用于分析 TCP 连接状态(如查看有多少 ESTABLISHED 或 TIME_WAIT 连接)。 |
📂 六、ls 命令:不仅仅是列出文件名
ls (List) 的核心价值在于排序和信息展示。在杂乱的日志目录或磁盘清理时,合适的参数能让你一眼看到关键信息。
1. 场景一:按时间排序(找最新日志/文件)
这是运维中最常用的场景之一。当你进入 /var/log 目录,想知道哪个日志文件刚刚被修改过:
| 命令示例 | 解释 |
|---|---|
ls -lt |
-t 按修改时间排序(倒序,最新的在最上面)。 |
ls -lrt |
-r (reverse) 反向排序。推荐用法:最新的文件会显示在终端的最下方,不用滚轮就能直接看到。 |
ls --full-time |
显示精确到毫秒的时间,用于排查并发文件生成的时间差。 |
2. 场景二:按大小排序(磁盘清理)
当磁盘报警时,需要快速找出当前目录下谁是“大胖子”:
| 命令示例 | 解释 | |
|---|---|---|
ls -lhS |
-S (大写) 按文件大小排序(大文件在前)。-h (human) 将字节转换为 KB/MB/GB 显示。 |
|
| `ls -lhS | head -5` | 只看最大的前 5 个文件。 |
3. 场景三:文件类型与隐藏文件
| 命令示例 | 解释 |
|---|---|
ls -a |
-a (all) 显示所有文件,包括以 . 开头的隐藏文件(如 .env, .ssh)。 |
ls -F |
在文件名后追加符号标识类型:/代表目录,*代表可执行文件,@代表软链接。方便直观区分。 |
🐱 七、cat 命令:拼接与特殊查看
cat 的全称是 Concatenate (拼接),它的本意是将文件连接起来,查看内容其实是它的副作用。
1. 场景一:辅助排查与格式检查
直接查看代码或配置时,有时候肉眼看不出的格式问题(如多余的空格、Tab混用)会导致程序报错。
| 命令示例 | 解释 |
|---|---|
cat -n file.py |
-n (number) 显示行号。在根据报错日志(如 “Error at line 42”)定位代码时非常有用。 |
cat -b file.txt |
-b 也是显示行号,但跳过空行不编号。 |
cat -A config.conf |
-A (All) 显示所有隐藏字符。它会用 ^I 表示 Tab 键,用 $ 表示行尾。排查配置文件格式错误(如 YAML/Python 缩进问题)的神器。 |
2. 场景二:文件合并与写入
利用 cat 的拼接特性,可以快速合并日志或创建小文件。
| 命令示例 | 解释 |
|---|---|
cat part1.log part2.log > full.log |
将 part1 和 part2 的内容首尾连接,合并写入 full.log。 |
cat > note.txt |
快速创建文件。输入命令后,直接在终端输入内容,按 Ctrl+D 保存退出。 |
cat /dev/null > access.log |
清空文件内容。将空设备重定向到日志文件,保留文件权限但清空内容(比 rm 安全)。 |
3. 补充:反向查看 tac
tac 是 cat 的反写,它的功能也是反的。
- 命令:
tac error.log | less - 场景:将文件内容从最后一行到第一行倒序显示。当你只关心日志末尾最新的报错,但又想往前追溯一点时,比
tail更灵活。
🔝 八、head & tail 命令:首尾截取
如果你只需要查看大型文件的开头或结尾(比如几万行的日志),而不希望让 cat 瞬间刷满屏幕,这两个命令是首选。
1. 场景一:快速预览与精确采样
| 命令示例 | 解释 |
|---|---|
head -n 20 data.csv |
查看文件的前 20 行。常用于查看数据文件的表头。 |
tail -n 20 server.log |
查看文件的最后 20 行。 |
tail -n +50 config.sh |
从第 50 行开始显示一直到末尾。 |
2. 场景二:实时监控(故障排查核心)
| 命令示例 | 解释 |
|---|---|
tail -f access.log |
-f (follow) 实时追踪。屏幕会保持打开,只要有新日志写入,它就会立即显示。 |
tail -F service.log |
-F 更稳健。如果文件被重命名或由于日志轮转(Rotation)被删除重建,它能自动重连。 |
🔍 九、less 命令:优雅的分页浏览
如果说 cat 是“一泻千里”,那么 less 就是“精准漫游”。它是 Linux 中查看大文件最专业、最推荐的方式,因为它不需要一次性加载整个文件,速度极快。
1. 为什么用 less 而不是 cat?
- 内存友好:打开 10GB 的日志文件,
cat会导致系统卡死,而less秒开。 - 交互性强:支持搜索、翻页、跳转,且不污染终端输出记录。
2. 交互快捷键(进入 less 后使用)
| 快捷键 | 功能 |
|---|---|
j / `k` |
向下一行 / 向上一行(同 Vim)。 |
空格 / `b` |
向下一页 (Forward) / 向上一页 (Backward)。 |
/关键词 |
向下搜索。输入后按 n 跳到下一个,按 N 跳到上一个。 |
?关键词 |
向上搜索。 |
G / `g` |
跳转到文件末尾 / 跳转到文件开头。 |
F |
进入“实时追踪模式”(类似 tail -f),按 Ctrl+C 退出该模式回到浏览模式。 |
q |
退出 (Quit)。 |
3. 命令组合
| 命令示例 | 解释 |
|---|---|
less -N file.py |
-N (Line Number) 在查看时显示行号。 |
| `dmesg | less` |
🕵️ 十一、文件查找神器:find 与 locate
在 Linux 中找文件,主要靠这两个命令:一个“地毯式搜索”(find),一个“查索引”(locate)。
1. find:全能但较慢的实时搜索
find 直接扫描磁盘,功能最强大,支持按文件名、大小、时间、权限等各种条件查找。
| 目标 | 命令示例 | 解释 |
|---|---|---|
| 按文件名查找 | find /etc -name "nginx.conf" |
在 /etc 目录下查找名为 nginx.conf 的文件。 |
| 忽略大小写查找 | find . -iname "readme.md" |
-i (ignore case) 忽略大小写。 |
| 按文件类型查找 | find . -type f -name "*.py" |
-type f (file) 只找文件,-type d (directory) 只找目录。 |
| 按文件大小查找 | find / -size +100M |
查找大于 100MB 的文件(+大于,-小于)。 |
| 按修改时间查找 | find . -mtime -7 |
查找最近 7 天内被修改过的文件。 |
进阶:找到并执行操作 (-exec)
这是 find 最强大的功能,可以对找到的每个文件执行特定的命令。
- 删除 30 天前的日志文件解释:
1
find /var/log -name "*.log" -mtime +30 -exec rm {} \;
{}代表找到的文件名,\;是命令结束的标记。
2. locate:极速但有延迟的索引搜索
locate 不扫描磁盘,而是查询系统内置的文件数据库(通常位于 /var/lib/mlocate/mlocate.db)。
- 优点:速度极快,毫秒级返回。
- 缺点:新建的文件可能找不到(因为数据库通常每天自动更新一次)。
| 目标 | 命令示例 | 解释 |
|---|---|---|
| 快速查找文件 | locate user_config |
只要路径中包含 user_config // filepath: e:\blog\myblogs\source_posts\linux_cmd.md |
// …existing code…
- find 命令:
find命令的参数非常特殊,通常不遵循这种捆绑规则(如find . -type f不能写成-tf)。
🕵️ 十、文件查找神器:find 与 locate
在 Linux 中找文件,主要靠这两个命令:一个“地毯式搜索”(find),一个“查索引”(locate)。
1. find:全能但较慢的实时搜索
find 直接扫描磁盘,功能最强大,支持按文件名、大小、时间、权限等各种条件查找。
| 目标 | 命令示例 | 解释 |
|---|---|---|
| 按文件名查找 | find /etc -name "nginx.conf" |
在 /etc 目录下查找名为 nginx.conf 的文件。 |
| 忽略大小写查找 | find . -iname "readme.md" |
-i (ignore case) 忽略大小写。 |
| 按文件类型查找 | find . -type f -name "*.py" |
-type f (file) 只找文件,-type d (directory) 只找目录。 |
| 按文件大小查找 | find / -size +100M |
查找大于 100MB 的文件(+大于,-小于)。 |
| 按修改时间查找 | find . -mtime -7 |
查找最近 7 天内被修改过的文件。 |
进阶:找到并执行操作 (-exec)
这是 find 最强大的功能,可以对找到的每个文件执行特定的命令。
- 删除 30 天前的日志文件解释:
1
find /var/log -name "*.log" -mtime +30 -exec rm {} \;
{}代表找到的文件名,\;是命令结束的标记。
2. locate:极速但有延迟的索引搜索
locate 不扫描磁盘,而是查询系统内置的文件数据库(通常位于 /var/lib/mlocate/mlocate.db)。
- 优点:速度极快,毫秒级返回。
- 缺点:新建的文件可能找不到(因为数据库通常每天自动更新一次)。
| 目标 | 命令示例 | 解释 |
|---|---|---|
| 快速查找文件 | locate user_config |
只要路径中包含 user_config |
十一、参数捆绑
简单来说:在 Linux 中,大部分命令(尤其是传统的 C 语言编写的命令,如 ls, cat, grep, tail)是支持将单字母参数组合在一起的。
这种组合方式通常被称为 “Short Option Bundling”(短参数捆绑)。
1. 组合规则
- 必须是单字母参数: 只有带单个连字符(
-)的单字母参数可以组合。 - 长参数不可组合: 带两个连字符(
--)的长参数(如--verbose)必须独立编写。 - 顺序通常不重要: 比如
ls -al和ls -la效果是一样的。 - 带值的参数除外: 如果某个参数后面需要紧跟一个值(比如
f参数后面要跟文件名),它通常必须放在组合的最后一位。
2. 常见示例
| 原始命令 | 组合后的命令 | 解释 |
|---|---|---|
ls -l -a -h |
ls -lah |
以列表形式 (-l)、显示隐藏文件 (-a)、人类可读格式 (-h) 列出文件。 |
ps -e -f |
ps -ef |
显示系统所有进程 (-e) 及完整格式 (-f)。 |
tar -c -v -f |
tar -cvf |
创建 (-c) 详细过程 (-v) 的归档文件。注意:f 必须在最后,因为后面要接文件名。 |
cat -n -v |
cat -nv |
显示行号 (-n) 并显示非打印字符 (-v)。 |
3. 特殊情况:带参数值的组合
这是一个非常重要的细节。如果一个参数需要指定具体的值,你不能把它放在中间。
❌ 错误示例:tar -cfv my_archive.tar .
这里 f 后面本应跟着文件名,但因为 v 在它后面,系统会误以为文件名是 v。
✅ 正确示例:tar -cvf my_archive.tar .
或者直接分开写:tar -cv -f my_archive.tar .
4. 为什么会有这种设计?
这是基于 POSIX 标准 和 GNU 编码规范 的传统。在早期的计算机系统中,由于终端输入效率较低,开发者倾向于使用尽可能少的字符来触发复杂的任务。
5. 并不是所有命令都支持
虽然大部分基础命令(如 ls, cat, rm, cp)都支持,但也有例外:
- Java 系列:
java -version看起来像短参数,但实际上它使用的是单个连字符引导的长单词,不能拆分(不能写成java -v -e -r...)。 - 部分现代工具: 一些用 Go 或 Rust 编写的新型 CLI 工具可能对参数解析有不同的逻辑。
- find 命令:
find命令的参数非常特殊,通常不遵循这种捆绑规则(如find . -type f不能写成-tf)。