文本处理工具
概述
Linux 提供了一套强大的文本处理工具,包括 sed、awk 等。这些工具可以高效地处理和转换文本数据。
sed - 流编辑器
sed(Stream Editor)是一个强大的文本处理工具,可以对文本进行过滤和转换。
基本语法
bash
sed [选项] '命令' 文件
sed [选项] -e '命令1' -e '命令2' 文件
sed [选项] -f 脚本文件 文件常用选项
| 选项 | 说明 |
|---|---|
-n | 静默模式,不自动打印 |
-e | 添加命令 |
-f | 从文件读取命令 |
-i | 直接修改文件 |
-i.bak | 修改前备份 |
-r / -E | 使用扩展正则表达式 |
替换命令 s
bash
# 基本替换(每行第一个)
$ sed 's/old/new/' file.txt
# 全局替换
$ sed 's/old/new/g' file.txt
# 忽略大小写
$ sed 's/old/new/gi' file.txt
# 只替换第 N 个匹配
$ sed 's/old/new/2' file.txt
# 显示被替换的行
$ sed -n 's/old/new/p' file.txt
# 直接修改文件
$ sed -i 's/old/new/g' file.txt
# 备份后修改
$ sed -i.bak 's/old/new/g' file.txt地址和范围
bash
# 指定行号
$ sed '3s/old/new/' file.txt # 第 3 行
$ sed '1,5s/old/new/' file.txt # 第 1-5 行
$ sed '3,$s/old/new/' file.txt # 第 3 行到最后
# 匹配模式的行
$ sed '/pattern/s/old/new/' file.txt
# 范围模式
$ sed '/start/,/end/s/old/new/' file.txt删除命令 d
bash
# 删除指定行
$ sed '3d' file.txt # 删除第 3 行
$ sed '1,5d' file.txt # 删除第 1-5 行
$ sed '$d' file.txt # 删除最后一行
# 删除匹配的行
$ sed '/pattern/d' file.txt
# 删除空行
$ sed '/^$/d' file.txt
# 删除注释行
$ sed '/^#/d' file.txt打印命令 p
bash
# 打印指定行
$ sed -n '3p' file.txt # 打印第 3 行
$ sed -n '1,5p' file.txt # 打印第 1-5 行
$ sed -n '$p' file.txt # 打印最后一行
# 打印匹配的行
$ sed -n '/pattern/p' file.txt
# 打印行号
$ sed -n '=' file.txt插入和追加
bash
# 在指定行前插入
$ sed '3i\新行内容' file.txt
# 在指定行后追加
$ sed '3a\新行内容' file.txt
# 在匹配行前后插入
$ sed '/pattern/i\插入内容' file.txt
$ sed '/pattern/a\追加内容' file.txt替换整行 c
bash
# 替换指定行
$ sed '3c\新内容' file.txt
# 替换匹配的行
$ sed '/pattern/c\新内容' file.txt多命令处理
bash
# 使用分号分隔
$ sed 's/a/A/g; s/b/B/g' file.txt
# 使用 -e 选项
$ sed -e 's/a/A/g' -e 's/b/B/g' file.txt
# 使用大括号分组
$ sed '/pattern/{s/old/new/; s/foo/bar/}' file.txt高级技巧
bash
# 使用不同的分隔符
$ sed 's|/usr/local|/opt|g' file.txt
$ sed 's#http://#https://#g' file.txt
# 引用匹配内容
$ sed 's/\(.*\)/【\1】/' file.txt # 添加括号
$ sed 's/[0-9]*/(&)/' file.txt # & 代表匹配内容
# 转换大小写
$ sed 's/[a-z]/\u&/g' file.txt # 首字母大写
$ sed 's/.*/\U&/' file.txt # 全部大写
$ sed 's/.*/\L&/' file.txt # 全部小写实用示例
bash
# 删除 HTML 标签
$ sed 's/<[^>]*>//g' file.html
# 删除行首空白
$ sed 's/^[ \t]*//' file.txt
# 删除行尾空白
$ sed 's/[ \t]*$//' file.txt
# 添加行号
$ sed = file.txt | sed 'N;s/\n/\t/'
# 每行后添加空行
$ sed 'G' file.txt
# 合并连续空行为一个
$ sed '/^$/N;/^\n$/d' file.txtawk - 模式处理语言
awk 是一种强大的文本处理语言,特别适合处理结构化数据。
基本语法
bash
awk 'pattern { action }' file
awk -F 分隔符 'pattern { action }' file内置变量
| 变量 | 说明 |
|---|---|
$0 | 整行内容 |
$1, $2, ... | 第 N 个字段 |
NF | 字段数量 |
NR | 当前行号 |
FNR | 当前文件的行号 |
FS | 字段分隔符 |
OFS | 输出字段分隔符 |
RS | 记录分隔符 |
ORS | 输出记录分隔符 |
FILENAME | 当前文件名 |
基本操作
bash
# 打印所有行
$ awk '{print}' file.txt
$ awk '{print $0}' file.txt
# 打印指定字段
$ awk '{print $1}' file.txt
$ awk '{print $1, $3}' file.txt
# 指定分隔符
$ awk -F ':' '{print $1}' /etc/passwd
$ awk -F ',' '{print $1, $2}' file.csv
# 打印行号
$ awk '{print NR, $0}' file.txt模式匹配
bash
# 匹配正则表达式
$ awk '/pattern/' file.txt
$ awk '/pattern/ {print $1}' file.txt
# 条件匹配
$ awk '$1 > 100' file.txt
$ awk '$1 == "value"' file.txt
$ awk 'NR > 5' file.txt
# 范围匹配
$ awk '/start/,/end/' file.txt
# 字段匹配
$ awk '$1 ~ /pattern/' file.txt
$ awk '$1 !~ /pattern/' file.txtBEGIN 和 END
bash
# BEGIN 在处理前执行
$ awk 'BEGIN {print "开始处理"} {print}' file.txt
# END 在处理后执行
$ awk '{print} END {print "处理完成"}' file.txt
# 设置变量
$ awk 'BEGIN {FS=":"; OFS="\t"} {print $1, $3}' /etc/passwd
# 统计行数
$ awk 'END {print NR}' file.txt算术运算
bash
# 基本运算
$ awk '{print $1 + $2}' file.txt
$ awk '{sum = $1 + $2; print sum}' file.txt
# 求和
$ awk '{sum += $1} END {print sum}' file.txt
# 平均值
$ awk '{sum += $1} END {print sum/NR}' file.txt
# 最大最小值
$ awk 'BEGIN {max=0} $1>max {max=$1} END {print max}' file.txt字符串函数
bash
# 长度
$ awk '{print length($1)}' file.txt
# 子串
$ awk '{print substr($1, 1, 3)}' file.txt
# 分割
$ awk '{split($1, arr, "-"); print arr[1]}' file.txt
# 替换
$ awk '{gsub(/old/, "new"); print}' file.txt
# 大小写转换
$ awk '{print toupper($1)}' file.txt
$ awk '{print tolower($1)}' file.txt
# 查找
$ awk '{if (index($0, "pattern") > 0) print}' file.txt控制结构
bash
# if-else
$ awk '{if ($1 > 100) print "大"; else print "小"}' file.txt
# for 循环
$ awk '{for (i=1; i<=NF; i++) print $i}' file.txt
# while 循环
$ awk '{i=1; while (i<=NF) {print $i; i++}}' file.txt
# 数组
$ awk '{count[$1]++} END {for (k in count) print k, count[k]}' file.txt格式化输出
bash
# printf
$ awk '{printf "%-10s %5d\n", $1, $2}' file.txt
# 格式说明符
# %s 字符串
# %d 整数
# %f 浮点数
# %- 左对齐
# %10 宽度实用示例
bash
# 统计词频
$ awk '{for(i=1;i<=NF;i++) count[$i]++} END {for(w in count) print count[w], w}' file.txt | sort -rn
# 计算文件大小总和
$ ls -l | awk '{sum += $5} END {print sum}'
# 处理 CSV
$ awk -F ',' '{print $1 "\t" $2}' file.csv
# 提取日志中的 IP
$ awk '{print $1}' access.log | sort | uniq -c | sort -rn
# 条件统计
$ awk '$3 > 1000 {count++} END {print count}' file.txt
# 合并行
$ awk 'ORS=NR%3?"\t":"\n"' file.txtdiff 和 patch
diff - 比较文件
bash
# 基本比较
$ diff file1.txt file2.txt
# 统一格式
$ diff -u file1.txt file2.txt
# 并排显示
$ diff -y file1.txt file2.txt
# 忽略空白
$ diff -w file1.txt file2.txt
# 递归比较目录
$ diff -r dir1/ dir2/
# 生成补丁
$ diff -u old.txt new.txt > changes.patchpatch - 应用补丁
bash
# 应用补丁
$ patch < changes.patch
# 指定文件
$ patch file.txt < changes.patch
# 反向应用(撤销)
$ patch -R < changes.patch
# 干运行
$ patch --dry-run < changes.patchcomm - 比较排序文件
bash
# 显示三列:只在文件1、只在文件2、两者共有
$ comm file1.txt file2.txt
# 只显示共有的行
$ comm -12 file1.txt file2.txt
# 只显示 file1 独有的行
$ comm -23 file1.txt file2.txtjoin - 连接文件
bash
# 基于公共字段连接
$ join file1.txt file2.txt
# 指定连接字段
$ join -1 2 -2 1 file1.txt file2.txt
# 指定分隔符
$ join -t ':' file1.txt file2.txt小结
本章介绍了 Linux 强大的文本处理工具:
- sed:流编辑器,适合简单的文本替换和转换
- awk:模式处理语言,适合结构化数据处理
- diff/patch:文件比较和补丁
- comm/join:文件合并和比较
掌握 sed 和 awk 将大大提高你的文本处理效率。
上一章:文本编辑器
下一章:正则表达式