先创建一个测试文件data.txt
# 创建并写入内容,执行后直接生成data.txt cat > data.txt << EOF 2026-01-01,张三,技术部,9000 2026-01-02,李四,市场部,8500 2026-01-03,王五,技术部,10000 2026-01-04,赵六,销售部,7500 2026-01-05,钱七,技术部,9500 # 这是员工薪资数据注释行 hello Linux HELLO SHELL EOF # 查看文件内容(验证创建成功) cat data.txt一、查看:读取文本文件内容
| 工具 | 通俗定位 | 核心语法 | 常用参数 | 示例(基于 data.txt) | 实用场景 |
|---|---|---|---|---|---|
cat | 小文件「一口气读完」 | cat [参数] 文件名 | -n:显示行号-b:仅显示非空行行号 | 1. 直接查看: 2. 带行号查看: | 查看几十行的小文件(配置片段、脚本日志) |
more | 大文件「翻书式阅读」 | more [参数] 文件名 | -num:指定每页显示行数 | more -3 data.txt→ 每页显示 3 行操作:空格翻页 /q退出 | 查看几百行的文件(程序运行日志) |
less | 升级版more(支持上下翻) | less [参数] 文件名 | -N:显示行号 | less -N data.txt操作:↑↓键翻行 /q退出 | 查看上千行的大文件(系统日志、数据库备份) |
head | 只看文件「前 N 行」(默认前 10 行) | head [-n 行数] 文件名 | -n N:查看前 N 行(默认 10 行) | 1. 默认前 10 行: 2. 前 3 行: | 快速确认文件开头(判断文件类型) |
tail | 只看文件「后 N 行 / 实时监控」(默认前 10 行) | tail [-n 行数] 文件名 | -n N:查看后 N 行-f:实时监控文件新增内容 | 1. 后 2 行: 2. 实时监控日志: | 查看日志最新内容(程序报错排查) |
关键补充:tail -f实时监控(运维必备)
当程序实时输出日志时,tail -f会持续显示新增内容,按Ctrl+C退出:
# 实时监控nginx日志新增内容 tail -f /var/log/nginx/access.log小贴士:小文件用cat,大文件用less,看头尾用head/tail。
二、筛选:从文本中筛选符合条件的行 / 内容
grep:全称Global Regular Expression Print,核心功能是在文本中查找匹配指定关键词 / 正则表达式的行,并将其输出,不修改原文件,是日常使用频率最高的文本工具。相当于 Word 的「查找(Ctrl+F)」功能,支持关键词和正则表达式匹配。
grep [可选参数] 「匹配模式」 「目标文件」 #语法 #匹配模式:可以是普通关键词(如 hello),也可以是正则表达式(如 ^Hello 匹配以 Hello 开头的行); #可选参数:用于增强匹配功能,常用参数如下(重点记前 4 个)。常用参数 :-i忽略大小写、-n显行号、-v反着找(找不包含的)
| 参数 | 功能 | 示例 | |
|---|---|---|---|
-i | 忽略大小写 | grep -i "hello" data.txt→ 匹配 包含hello/HELLO的所在行 | grep 默认区分大小写 |
-n | 显示匹配行的行号 | grep -n "技术部" data.txt→ 显示技术部所在行号 | |
-v | 反向匹配(输出不包含的行) | grep -v "^#" data.txt→ 过滤注释行(# 开头的行) | |
-r | 递归查找目录下所有文件 | grep -r "error" /var/log/→ 查找日志目录下所有含 error 的文件 | |
-E | 支持扩展正则表达式 | `grep -E" 技术部 | 市场部 "data.txt` → 匹配技术部或市场部 |
| -o | 仅输出匹配到的内容(而非整行) |
实操示例1(基于 data.txt)
# 1. 查找包含"技术部"的行 grep "技术部" data.txt # 输出: # 2026-01-01,张三,技术部,9000 # 2026-01-03,王五,技术部,10000 # 2026-01-05,钱七,技术部,9500 # 2. 过滤注释行(输出非#开头的行) grep -v "^#" data.txt # 3. 正则匹配:查找以数字开头的行(薪资数据行) grep "^[0-9]" data.txt #^行首、$行尾、[]字符集、*任意次实操示例2
# 1. 创建并写入内容(直接复制粘贴到终端执行) cat > test.txt << EOF Hello Shell hello Linux This is a test file Test Line 1 Test Line 2 100,张三,25 200,李四,30 300,王五,28 EOF # 2. 查看文件内容(验证创建成功) cat test.txt ---- 查找包含指定关键词的行-------------------------- # 查找包含 "Test" 的行 grep "Test" test.txt #输出结果 This is a test file Test Line 1 Test Line 2 #grep 默认区分大小写,只匹配大写 Test,小写 test 也被匹配(因为是子串) ------忽略大小写匹配(-i 参数)-------------------- # 查找包含 "hello" 的行,忽略大小写 grep -i "hello" test.txt #输出结果 Hello Shell hello Linux ------显示匹配行的行号(-n 参数)--------------------- # 查找包含 "Test" 的行,并显示行号 grep -n "Test" test.txt #输出结果 3:This is a test file 4:Test Line 1 5:Test Line 2 -------反向匹配(-v 参数)—— 输出不包含指定关键词的行---------- # 输出不包含 "Test"(不区分大小写)的所有行 grep -iv "Test" test.txt #输出结果 Hello Shell hello Linux 100,张三,25 200,李四,30 300,王五,28 ---------正则表达式匹配 —— 匹配以数字开头的行------------------------ # 匹配以 [0-9] 开头的行(^ 表示行首,[0-9] 表示单个数字) grep "^[0-9]" test.txt #输出结果 100,张三,25 200,李四,30 300,王五,28 ------------------------------------------------------实用场景
- 日志报错排查:
grep -n "ERROR" app.log→ 定位报错行号 - 配置文件去注释:
grep -v "^#" config.conf > new.conf→ 生成无注释的配置文件
三、编辑:批量修改文本
核心作用:批量替换、删除、新增文本内容,无需手动打开文件
工具 1:sed(流式编辑神器):全称Stream Editor(流式编辑器),核心功能是按行对文本进行批量编辑(替换、删除、新增、修改),默认不修改原文件(仅输出到终端),支持原地修改,是批量处理文本的核心工具。相当于 Word 的「查找替换(Ctrl+H)」功能。
核心语法
sed [参数] "编辑命令" 文件名核心编辑命令
| 命令 | 功能 | 语法示例 |
|---|---|---|
s | 替换内容(最常用) | s/旧内容/新内容/g→g表示全局替换 |
d | 删除行 | /匹配模式/d→ 删除包含模式的行 |
a | 行后追加内容 | 行号a 追加内容→ 在指定行后加内容 |
i | 行前插入内容 | 行号i 插入内容→ 在指定行前加内容 |
p | 打印行 | 行号p→ 打印指定行(需配合-n参数) |
常用参数
| 参数 | 功能 | 示例 |
|---|---|---|
-n | 静默模式:仅输出「被处理过」的行,不输出所有行(配合p命令使用) | sed -n "3p" data.txt→ 仅打印第 3 行 |
-i | 原地修改原文件(直接修改文件内容,无输出,谨慎使用!建议先备份) | sed -i.bak 's/技术部/研发部/g' data.txt→ 备份原文件为 data.txt.bak |
-e | 执行多个编辑命令(用分号分隔,或多次使用-e) | sed -e 's/张三/小张/g' -e '/销售部/d' data.txt |
| -f | 从脚本文件中读取编辑命令(适合复杂操作) |
实操示例1(基于 data.txt)
# 1. 全局替换:将"技术部"替换为"研发部"(不修改原文件) sed 's/技术部/研发部/g' data.txt # 2. 删除行:删除包含"销售部"的行 sed '/销售部/d' data.txt # 3. 插入内容:在第4行后追加"2026-01-06,孙八,研发部,8000" sed '4a 2026-01-06,孙八,研发部,8000' data.txt # 4. 原地修改+备份(生产环境必备) sed -i.bak 's/市场部/营销部/g' data.txt # 原文件备份为data.txt.bak,data.txt被修改关键补充:s替换命令的「标记」
sed 's/旧/新/标记'中的标记用于增强替换功能,常用:
g:全局替换(行内所有匹配项都替换,默认只替换第一个);i:忽略大小写(仅部分sed版本支持);数字:替换行内第n个匹配项(如s/Test/TEST/2替换第 2 个Test)。
实操示例2
# 1. 创建并写入内容(直接复制粘贴到终端执行) cat > test.txt << EOF Hello Shell hello Linux This is a test file Test Line 1 Test Line 2 100,张三,25 200,李四,30 300,王五,28 EOF # 2. 查看文件内容(验证创建成功) cat test.txt 示例 1:基础替换 —— 替换行内第一个匹配项 bash 运行 # 把每行中第一个 "Test" 替换为 "TEST"(默认不修改原文件,仅输出结果) sed 's/Test/TEST/' test.txt 输出结果(关键变化): plaintext This is a TEST file TEST Line 1 TEST Line 2 说明:仅替换每行第一个 Test,原文件 test.txt 内容不变。 示例 2:全局替换 —— 替换行内所有匹配项(g 标记) bash 运行 # 把所有 "Hello/hello"(不区分大小写)替换为 "Hi",全局替换 sed 's/hello/Hi/gi' test.txt 输出结果(关键变化): plaintext Hi Shell Hi Linux 示例 3:删除指定行(d 命令) bash 运行 # 示例3.1:删除第3行 sed '3d' test.txt # 示例3.2:删除所有包含 "Test" 的行(不区分大小写) sed '/Test/Id' test.txt # 示例3.3:删除以数字开头的行(正则匹配) sed '/^[0-9]/d' test.txt 示例 4:追加 / 插入内容(a/i 命令) bash 运行 # 示例4.1:在第5行后追加 "Test Line 3" sed '5a Test Line 3' test.txt # 示例4.2:在以数字开头的行前插入 "=== 数据分割线 ===" sed '/^[0-9]/i === 数据分割线 ===' test.txt 示例 5:原地修改原文件(-i 参数,谨慎使用) bash 运行 # 先备份原文件(推荐:在 -i 后加备份后缀,如 .bak) sed -i.bak 's/Test/TEST/g' test.txt # 查看修改后的原文件 cat test.txt # 查看备份文件(原文件内容保留在 test.txt.bak 中) cat test.txt.bak实用场景
- 批量修改配置文件:
sed -i.bak 's/old_ip/192.168.1.100/g' /etc/nginx/*.conf - 清理日志空行:
sed '/^$/d' app.log > clean.log(^$匹配空行) - 替换:
s/旧内容/新内容/g→s= 替换,g= 全局替换(所有匹配项) - 删除:
/要删的内容/d→d= 删除 - 原地修改:加
-i.bak(一定要加.bak备份!)
工具 2:tr(字符级替换 / 转换):专门处理「单个字符」的替换、删除、转换,比如大小写转换。
核心语法
# 方式1:处理文件内容 cat 文件名 | tr "原字符" "新字符" # 方式2:处理输入内容 echo "内容" | tr "原字符" "新字符" # | 叫管道符,把前一个命令的结果传给后一个命令,像流水线一样。实操示例
# 1. 小写转大写:将data.txt中所有小写字母转大写 cat data.txt | tr a-z A-Z # 2. 删除指定字符:删除所有逗号 cat data.txt | tr -d "," # 3. 压缩重复字符:将多个连续空格压缩为1个 echo "hello world shell" | tr -s " "四、分割:按列分割 / 分析文本
核心作用:处理结构化文本(如 CSV、日志),按列提取或分析数据
工具 1:cut(简单列提取):相当于 Excel 的「提取某一列」,适合分隔符清晰的文本。
核心语法
cut [-d 分隔符] [-f 列数] 文件名关键参数
| 参数 | 功能 |
|---|---|
-d | 指定列分隔符(默认是制表符\t) |
-f | 指定要提取的列(列数从 1 开始,多个列用逗号分隔) |
实操示例(基于 data.txt,分隔符为逗号)
# 1. 提取第2列(姓名)和第4列(薪资) cut -d "," -f 2,4 data.txt # 输出: # 张三,9000 # 李四,8500 # ... # 2. 提取第3列(部门),并去重统计 cut -d "," -f 3 data.txt | grep -v "#" | sort | uniq -c局限:cut不支持「多个空格作为分隔符」的场景(比如日志中不规则空格),此时用awk更合适。
工具 2:awk(文本分析神器,重点):以发明者(Aho、Weinberger、Kernighan)命名的工具,核心功能是按「行」处理文本,按「列」分割数据,支持变量、循环、条件判断,能完成复杂的数据筛选、统计和格式化输出,相当于「轻量级 Excel + 简易编程语言」,支持按列处理、条件判断、统计计算,是结构化文本分析的核心工具。
核心语法(三段式结构)
awk [参数] ' BEGIN{初始化操作} {行处理逻辑} END{收尾统计} ' 文件名- 三段式结构(灵活组合,可省略
BEGIN和END):BEGIN{}:处理文本前执行(仅执行 1 次),用于初始化变量、设置输出格式;{}:处理文本时,对「每一行」都执行一次(核心逻辑);END{}:处理完所有文本后执行(仅执行 1 次),用于统计结果、输出汇总;
- 可选参数:常用
-F(指定列分隔符)、-v(定义自定义变量)。
关键基础
(1)列分隔符(-F参数)
awk默认以「空格 / 制表符」作为列分隔符,将每行数据分割为多个列;- 用
-F参数可指定自定义分隔符(如逗号,、冒号:等),适合处理 CSV 格式文件。
(2)内置变量(常用,无需定义直接使用)
| 内置变量 | 功能 | 示例 |
|---|---|---|
$0 | 当前处理行的完整内容 | {print $0}→ 输出整行 |
$1~$n | 当前行的第 1~n 列(列从 1 开始) | {print $2}→ 输出第 2 列 |
NR | 当前处理行的行号 | NR>1 {print $0}→ 跳过第一行 |
NF | 当前行的列数 | {print NF}→ 输出当前行列数 |
-F | 指定列分隔符(等价于BEGIN{FS="分隔符"}) | awk -F "," '{print $3}' data.txt |
实操示例1(基于 data.txt,分隔符为逗号)
# 示例1:基础列提取——提取姓名($2)和薪资($4) awk -F "," '{print $2 " → " $4 "元"}' data.txt # 示例2:条件筛选——提取技术部薪资>9000的员工 awk -F "," '$3=="技术部" && $4>9000 {print $2, $4}' data.txt # 输出: # 王五 10000 # 钱七 9500 # 示例3:统计分析——计算技术部平均薪资 awk -F "," ' BEGIN{ sum=0; count=0; # 初始化总和和人数 } $3=="技术部"{ sum+=$4; count++; # 累加薪资和人数 } END{ print "技术部总人数:" count; print "技术部平均薪资:" sum/count "元"; } ' data.txt实操示例2
# 1. 创建并写入内容(直接复制粘贴到终端执行) cat > test.txt << EOF Hello Shell hello Linux This is a test file Test Line 1 Test Line 2 100,张三,25 200,李四,30 300,王五,28 EOF # 2. 查看文件内容(验证创建成功) cat test.txt 示例 1:基础列提取 —— 按列分割数据 bash 运行 # 示例1.1:提取所有行的第1列(默认分隔符:空格) awk '{print $1}' test.txt # 示例1.2:提取CSV数据的第2列(姓名),指定分隔符为逗号(-F ,) awk -F ',' '{print $2}' test.txt 示例 1.2 输出结果: plaintext 张三 李四 王五 示例 2:带条件判断的行筛选 —— 提取满足条件的数据 bash 运行 # 示例2.1:提取行号大于5的行(即CSV数据行) awk 'NR > 5 {print $0}' test.txt # 示例2.2:提取年龄大于28的用户信息(CSV第3列是年龄,分隔符为逗号) awk -F ',' '$3 > 28 {print $2 " " $3}' test.txt 示例 2.2 输出结果: plaintext 李四 30 示例 3:数据统计 —— 求和、计数(配合 END{}) bash 运行 # 统计所有用户的年龄总和与平均年龄(CSV第3列是年龄) awk -F ',' ' BEGIN{ sum_age=0; # 初始化年龄总和变量 count=0; # 初始化用户计数变量 } NR > 5 { # 仅处理CSV数据行 sum_age += $3; # 累加年龄 count += 1; # 累加用户数 print $2 ":" $3 "岁"; } END{ print "=== 统计结果 ==="; print "用户总数:" count; print "年龄总和:" sum_age; print "平均年龄:" sum_age / count; } ' test.txt 输出结果: plaintext 张三:25岁 李四:30岁 王五:28岁 === 统计结果 === 用户总数:3 年龄总和:83 平均年龄:27.6667 示例 4:格式化输出 —— 美化文本格式 bash 运行 # 给CSV数据添加表头和格式,按「序号 姓名 年龄」输出 awk -F ',' ' BEGIN{ print "序号\t姓名\t年龄"; # \t 表示制表符,对齐格式 print "---------------------"; } NR > 5 { print NR-5 "\t" $2 "\t" $3; # NR-5 作为用户序号 } ' test.txt 输出结果: plaintext 序号 姓名 年龄 --------------------- 1 张三 25 2 李四 30 3 王五 28实用场景
- Nginx 日志分析:统计每个 IP 的访问次数
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr - CSV 数据统计:计算销售部薪资总和
awk -F "," '$3=="销售部"{sum+=$4} END{print sum}' sales.csv
五、排序:整理文本顺序 / 去重
核心作用:对文本行排序,删除重复行
工具 1:sort(文本排序)
- 核心语法
sort [参数] 文件名- 常用参数
参数 | 功能 | 示例 |
|---|---|---|
| 按数字大小排序(默认按字符排序) |
|
| 反向排序(降序) |
|
| 指定按第 k 列排序 |
|
| 指定列分隔符 | 同上,分隔符为逗号 |
| 去重(排序后删除重复行) |
|
- 实操示例
# 按薪资(第4列)降序排序(分隔符为逗号) sort -t "," -k 4nr data.txt工具 2:uniq(删除重复行)
- 核心语法
sort 文件名 | uniq [参数]注意:
uniq只能删除连续重复的行,因此必须先排序。
- 常用参数
参数 | 功能 |
|---|---|
| 统计重复行的次数 |
| 仅显示重复的行 |
| 仅显示不重复的行 |
- 实操示例
# 统计data.txt中各部门的出现次数 cut -d "," -f 3 data.txt | grep -v "#" | sort | uniq -c # 输出: # 1 市场部 # 3 技术部 # 1 销售部六、统计:文本指标统计
wc(统计行数 / 单词数 / 字符数)
核心语法
wc [参数] 文件名常用参数
参数 | 功能 | 示例 |
|---|---|---|
| 统计行数 |
|
| 统计单词数 |
|
| 统计字符数 |
|
实操示例
# 统计data.txt的行数(排除注释行) grep -v "^#" data.txt | wc -l七、 工具组合:管道符(|)
文本处理的精髓是「工具组合使用」,通过管道符|将多个工具串联,完成复杂任务。管道符的作用是:将前一个命令的输出,作为后一个命令的输入。
- 经典组合示例
需求:统计 data.txt 中技术部薪资 > 8000 的员工人数
# 步骤1:过滤注释行 → 步骤2:按逗号分割 → 步骤3:筛选技术部且薪资>8000 → 步骤4:统计行数 grep -v "^#" data.txt | awk -F "," '$3=="技术部" && $4>8000 {print $0}' | wc -l需求:分析 Nginx 日志中访问量最高的前 5 个 IP
# 步骤1:提取IP列 → 步骤2:排序 → 步骤3:统计次数 → 步骤4:降序排序 → 步骤5:取前5个 awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -n 5