06 文本处理
学习目标
- 能对文本排序、去重和统计。
- 能按分隔符提取字段。
- 能做简单的文本替换和批量处理。
命令总览
| 命令 | 用途 | 含义 | 基本用法 | 例子 |
|---|---|---|---|---|
sort | 排序文本行 | 按字典序或数字顺序排序 | sort 文件 | sort names.txt |
uniq | 去除相邻重复行 | unique,通常配合 sort 使用 | uniq 文件 | sort names.txt | uniq |
cut | 按列截取文本 | 根据字符位置或分隔符取字段 | cut [选项] 文件 | cut -d ":" -f 1 /etc/passwd |
awk | 文本分析和按列处理 | 适合按字段处理文本 | awk '规则' 文件 | awk '{print $1}' app.log |
sed | 流式文本编辑 | 常用于替换、删除、打印行 | sed '表达式' 文件 | sed 's/old/new/g' file.txt |
tr | 字符替换或删除 | translate,对字符级别处理 | tr '原字符' '新字符' | printf '%s\n' abc | tr '[:lower:]' '[:upper:]' |
xargs | 把 NUL 分隔输入转为参数 | 普通换行不能表示所有合法文件名;GNU/Linux 配合 -print0/-0 | find ... -print0 | xargs -0 命令 | find . -type f -name '*.log' -print0 | xargs -0 -- wc -l |
常用场景
排序并去重:
sort names.txt | uniq
sort names.txt | uniq -c提取冒号分隔文件的第一列:
cut -d ":" -f 1 /etc/passwd提取日志第一列:
awk '{print $1}' app.log替换文本中的内容:
sed 's/error/ERROR/g' app.log把小写转大写:
printf '%s\n' 'linux' | LC_ALL=C tr '[:lower:]' '[:upper:]'把搜索到的文件安全交给另一个命令处理:
find . -type f -name '*.log' -exec wc -l -- {} +
find . -type f -name '*.log' -print0 | xargs -0 -- wc -l新手注意
uniq只去除相邻重复行,所以通常先sort再uniq。sed 's/old/new/g' file默认只输出结果,不会修改原文件。sed -i不是 POSIX,GNU 与 BSD/macOS 对-i和备份后缀的语法不同。课程先输出到新文件并比较,不直接原地改写。awk默认按空白字符分列,$1是第一列,$2是第二列。- 普通换行管道不能安全表示所有合法文件名;便携首选
find -exec ... {} +,GNU/Linux 可用-print0 | xargs -0。 - 排序、大小写和字符类受 locale 影响;需要可复现字节顺序时显式使用
LC_ALL=C。
不覆盖原文件的替换练习
sed 's/error/ERROR/g' -- app.log > app.log.new
cmp --silent -- app.log app.log.new
cmp_rc=$?
printf 'content_changed=%s\n' "$cmp_rc"先检查 app.log.new,再决定是否用受控 mv 替换;不要把输出重定向回输入文件。
掌握检查
- 能解释
uniq为什么通常需要已排序输入。 - 能处理含空格和换行的文件名,不用裸
find | xargs。 - 知道 sed 原地编辑和 locale 存在平台差异。