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/-0find ... -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 存在平台差异。

参考资料