跳到主要内容

文本处理

Linux 提供了强大的文本处理工具,可以高效地搜索、过滤、转换文本内容。

grep - 文本搜索

grep 是最常用的文本搜索工具,用于在文件中查找匹配模式的行。

基本用法

# 在文件中搜索字符串
grep "pattern" file.txt

# 搜索多个文件
grep "pattern" file1.txt file2.txt

# 递归搜索目录
grep -r "pattern" /path/to/dir

# 忽略大小写
grep -i "pattern" file.txt

# 显示行号
grep -n "pattern" file.txt

# 显示不匹配的行
grep -v "pattern" file.txt

常用选项

选项说明
-i忽略大小写
-v反向匹配(显示不匹配的行)
-n显示行号
-c只显示匹配行数
-l只显示文件名
-r递归搜索目录
-w匹配整个单词
-A n显示匹配行及后 n 行
-B n显示匹配行及前 n 行
-C n显示匹配行及前后各 n 行
-E使用扩展正则表达式

正则表达式

# 使用正则表达式
grep -E "^error" file.txt # 以 error 开头
grep -E "error$" file.txt # 以 error 结尾
grep -E "[0-9]+" file.txt # 包含数字
grep -E "a.b" file.txt # a 和 b 之间有任意字符
grep -E "a*b" file.txt # a 出现 0 次或多次
grep -E "a+b" file.txt # a 出现 1 次或多次
grep -E "(abc)+" file.txt # abc 出现 1 次或多次
grep -E "a\|b" file.txt # a 或 b

# 常用正则模式
grep -E "[a-zA-Z]+" file.txt # 字母
grep -E "[0-9]{3}" file.txt # 三个数字
grep -E "[0-9]{3,5}" file.txt # 3 到 5 个数字

实际应用

# 查找包含 error 的日志
grep -i "error" /var/log/syslog

# 查找特定用户的登录记录
grep "username" /var/log/auth.log

# 统计匹配行数
grep -c "error" application.log

# 查找配置文件中的非注释行
grep -v "^#" /etc/ssh/sshd_config | grep -v "^$"

# 查找 IP 地址
grep -E "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" access.log

sed - 流编辑器

sed 是一个强大的流编辑器,用于文本转换和替换。

基本语法

sed [选项] '命令' 文件

替换操作

# 替换每行第一个匹配
sed 's/old/new/' file.txt

# 替换每行所有匹配
sed 's/old/new/g' file.txt

# 只替换第 n 个匹配
sed 's/old/new/2' file.txt

# 替换特定行
sed '3s/old/new/' file.txt # 第 3 行
sed '3,5s/old/new/' file.txt # 第 3-5 行

# 使用不同的分隔符
sed 's#/old#/new#' file.txt # 适合处理路径

# 忽略大小写
sed 's/old/new/gi' file.txt

删除操作

# 删除匹配行
sed '/pattern/d' file.txt

# 删除空行
sed '/^$/d' file.txt

# 删除注释行
sed '/^#/d' file.txt

# 删除指定行
sed '3d' file.txt # 删除第 3 行
sed '3,5d' file.txt # 删除第 3-5 行
sed '$d' file.txt # 删除最后一行

插入和追加

# 在匹配行前插入
sed '/pattern/i\新行内容' file.txt

# 在匹配行后追加
sed '/pattern/a\新行内容' file.txt

# 在文件开头插入
sed '1i\标题' file.txt

# 在文件末尾追加
sed '$a\结尾' file.txt

修改文件

# 直接修改文件(慎用)
sed -i 's/old/new/g' file.txt

# 创建备份后修改
sed -i.bak 's/old/new/g' file.txt

实际应用

# 移除 HTML 标签
sed 's/<[^>]*>//g' file.html

# 删除行首空格
sed 's/^[ \t]*//' file.txt

# 删除行尾空格
sed 's/[ \t]*$//' file.txt

# 替换 Windows 换行符为 Unix 格式
sed 's/\r$//' file.txt

# 在每行开头添加内容
sed 's/^/prefix /' file.txt

# 在每行末尾添加内容
sed 's/$/ suffix/' file.txt

awk - 文本处理语言

awk 是一个强大的文本处理语言,适合处理结构化数据。

基本语法

awk '模式 { 动作 }' 文件

基本用法

# 打印整行
awk '{ print }' file.txt

# 打印第一列
awk '{ print $1 }' file.txt

# 打印第一和第三列
awk '{ print $1, $3 }' file.txt

# 打印最后一列
awk '{ print $NF }' file.txt

# 打印行号
awk '{ print NR, $0 }' file.txt

# 打印列数
awk '{ print NF }' file.txt

指定分隔符

# 使用逗号作为分隔符
awk -F',' '{ print $1 }' file.csv

# 使用制表符作为分隔符
awk -F'\t' '{ print $1 }' file.tsv

# 使用多个分隔符
awk -F'[,:]' '{ print $1 }' file.txt

条件过滤

# 打印第三列大于 100 的行
awk '$3 > 100 { print }' file.txt

# 打印第一列等于特定值的行
awk '$1 == "value" { print }' file.txt

# 打印包含特定模式的行
awk '/pattern/ { print }' file.txt

# 组合条件
awk '$3 > 100 && $3 < 200 { print }' file.txt

内置变量

变量说明
$0当前整行
$1, $2...第 1, 2... 列
NF当前行的列数
NR当前行的行号
FS字段分隔符
RS行分隔符
OFS输出字段分隔符
ORS输出行分隔符
FILENAME当前文件名

BEGIN 和 END

# BEGIN:处理前执行
# END:处理后执行
awk 'BEGIN { print "开始处理" }
{ print $1 }
END { print "处理完成" }' file.txt

# 计算总和
awk '{ sum += $1 } END { print sum }' numbers.txt

# 计算平均值
awk '{ sum += $1 } END { print sum/NR }' numbers.txt

# 统计行数
awk 'END { print NR }' file.txt

实际应用

# 处理日志文件
awk '{ print $1 }' access.log | sort | uniq -c | sort -rn | head -10

# 提取特定字段
awk -F':' '{ print $1 }' /etc/passwd

# 计算文件大小总和
ls -l | awk '{ sum += $5 } END { print sum }'

# 格式化输出
awk '{ printf "%-10s %5d\n", $1, $2 }' file.txt

# 筛选特定范围的行
awk 'NR >= 10 && NR <= 20' file.txt

cut - 列提取

cut 命令用于提取文件中的列。

基本用法

# 提取第 2 列(按字节)
cut -b 2 file.txt

# 提取第 2-5 列(按字节)
cut -b 2-5 file.txt

# 提取指定字段
cut -f 1 file.txt

# 指定分隔符
cut -d':' -f 1 /etc/passwd

# 提取多个字段
cut -d':' -f 1,3,7 /etc/passwd

# 提取字段范围
cut -d':' -f 1-3 /etc/passwd

sort - 排序

sort 命令用于对文本行进行排序。

基本用法

# 默认排序(按字典序)
sort file.txt

# 数字排序
sort -n file.txt

# 逆序排序
sort -r file.txt

# 按指定列排序
sort -k 2 file.txt

# 按指定列数字排序
sort -k 2 -n file.txt

# 指定分隔符
sort -t':' -k 3 -n /etc/passwd

# 去重
sort -u file.txt

# 检查是否已排序
sort -c file.txt

uniq - 去重

uniq 命令用于去除重复行(必须先排序)。

基本用法

# 去除连续重复行
sort file.txt | uniq

# 显示重复次数
sort file.txt | uniq -c

# 只显示重复行
sort file.txt | uniq -d

# 只显示不重复行
sort file.txt | uniq -u

# 忽略大小写
sort file.txt | uniq -i

wc - 统计

wc 命令用于统计文件的行数、单词数和字节数。

基本用法

# 统计行数
wc -l file.txt

# 统计单词数
wc -w file.txt

# 统计字节数
wc -c file.txt

# 统计字符数(多字节字符)
wc -m file.txt

# 统计所有
wc file.txt

tr - 字符转换

tr 命令用于转换或删除字符。

基本用法

# 转换小写为大写
echo "hello" | tr 'a-z' 'A-Z'

# 转换大写为小写
echo "HELLO" | tr 'A-Z' 'a-z'

# 删除字符
echo "hello123" | tr -d '0-9'

# 删除非数字字符
echo "hello123" | tr -cd '0-9'

# 压缩重复字符
echo "hello world" | tr -s ' '

# 删除换行符
cat file.txt | tr -d '\n'

head 和 tail - 查看文件头尾

# 查看文件前 10 行
head file.txt

# 查看文件前 n 行
head -n 20 file.txt

# 查看文件后 10 行
tail file.txt

# 查看文件后 n 行
tail -n 20 file.txt

# 实时查看文件末尾(日志监控)
tail -f /var/log/syslog

# 查看文件中间部分
head -n 50 file.txt | tail -n 20

实战示例

日志分析

# 统计访问量最大的 IP
awk '{ print $1 }' access.log | sort | uniq -c | sort -rn | head -10

# 统计 HTTP 状态码
awk '{ print $9 }' access.log | sort | uniq -c | sort -rn

# 查找特定时间段的日志
awk '/2024-01-01 10:00/,/2024-01-01 11:00/' access.log

# 统计每小时的请求量
awk '{ print substr($4, 14, 2) }' access.log | sort | uniq -c

数据处理

# CSV 文件处理
awk -F',' '{ print $1, $3 }' data.csv

# 提取 JSON 中的字段(需要 jq)
cat data.json | jq '.name'

# 合并两个文件的行
paste file1.txt file2.txt

# 比较两个文件
diff file1.txt file2.txt

小结

本章我们学习了:

  1. grep:文本搜索和正则匹配
  2. sed:流编辑和文本替换
  3. awk:结构化数据处理
  4. cut:列提取
  5. sort:排序
  6. uniq:去重
  7. wc:统计
  8. tr:字符转换
  9. head/tail:查看文件头尾

练习

  1. 使用 grep 查找 /var/log 目录下所有包含 "error" 的日志行
  2. 使用 sed 替换文件中的所有空格为下划线
  3. 使用 awk 计算 /etc/passwd 文件中的用户数量
  4. 使用管道组合多个命令分析日志文件