Linux 文本处理与搜索命令速查
更新时间:2026-08-28。本文是 Linux 命令速查主题第②族:文本处理与搜索,约 36 个命令。日志、配置、CSV、命令输出——Linux 世界里几乎一切都是文本,因此这族命令的使用频率高得离谱。所谓"文本处理三剑客"指的是 grep(找)、sed(改)、awk(算),三者配合管道能完成绝大多数数据加工,不用写一行脚本。深入讲解见 Shell 文本处理。
一、查看与浏览
看日志的基本动作就三个:cat 看短的、less 翻长的、tail -f 跟实时的。选错了工具会很痛苦——用 cat 打开一个几百 MB 的日志,等同于让终端卡死几分钟。
| 命令 | 作用 | 常用示例 |
|---|---|---|
| cat | 连接并输出文件内容,适合短文件 | cat file;cat -n file(显示行号);cat a b > c(合并);cat -A(显示不可见字符,查隐藏的 ^M 很有用) |
| tac | 反向输出(从最后一行到第一行),名字就是 cat 倒过来 | tac file(倒序看,找最近的记录方便) |
| rev | 把每行字符反转 | rev file;echo abc | rev → cba |
| less | 分页查看,支持前后翻页与搜索,看大文件首选 | less /var/log/syslog;进入后 / 搜索、n 下一个、G 跳到末尾、q 退出;less +F file(等同 tail -f,可 Ctrl-C 退出跟踪) |
| head | 查看文件开头 | head -n 20 file;head -c 100 file(前 100 字节);head -n -5 file(去掉最后 5 行) |
| tail | 查看文件结尾 | tail -n 50 file;tail -f file(实时跟踪);tail -F file(文件被轮转后自动重开,跟踪日志必备);tail -n +2 file(从第 2 行开始,去掉表头) |
| nl | 带行号输出 | nl file;nl -ba file(所有行都编号,含空行) |
tail -f和tail -F的区别值得记住:-f按文件描述符跟踪,日志文件被 logrotate 重命名后它就断了;-F按文件名跟踪,文件被换掉后会自动重新打开。长期跟日志一律用-F。看大文件千万别 cat,less 是按需读取的,打开几个 G 的文件也是秒开。
二、搜索与过滤
grep 用正则表达式(regex,用特殊字符描述字符串模式的语法)匹配文本。它是三剑客里用得最多的一个,也是排查问题的第一反应——"在日志里找 error"。
| 命令 | 作用 | 常用示例 |
|---|---|---|
| grep | 按正则搜索文本并输出匹配行 | grep "error" log.txt;grep -i(忽略大小写);grep -r(递归目录);grep -v(反选,排除匹配行);grep -c(只计数);grep -n(显示行号);grep -E(扩展正则);grep -A3 -B3(显示匹配行的前后 3 行上下文) |
egrep | grep 的扩展正则别名,等价于 grep -E | egrep 'err|warn' log(匹配多个模式) |
fgrep | 固定字符串搜索,不做正则解析,因此最快且 .、* 等按字面处理 | fgrep 'a.b' file(点号就是点号) |
| strings | 从二进制文件中提取可读字符串,排查未知二进制时很有用 | strings /bin/ls | grep usage;strings -n 8 file(至少 8 个字符) |
| look | 按字典序查找以指定前缀开头的行(需文件已排序) | look "app" /usr/share/dict/words |
grep -v是过滤噪音的利器:grep -v "^#" config去掉所有注释行,ps aux | grep nginx | grep -v grep排除掉 grep 自己。注意 grep 的退出码可以直接用于判断:找到返回 0,没找到返回 1——脚本里if grep -q pattern file; then是标准写法。
三、行处理与转换
这一节是三剑客里的 sed 和 awk。sed(stream editor,流编辑器)逐行处理文本,最常用的是替换;awk 则是按字段(列)处理,自带变量、循环和条件,实际上是一门小型编程语言——统计、求和、格式化报表都能做。
| 命令 | 作用 | 常用示例 |
|---|---|---|
| cut | 按分隔符或字符位置切出指定列 | cut -d: -f1 /etc/passwd(以 : 分割取第 1 列);cut -d, -f1,3 data.csv(多列);cut -c1-10 file(取前 10 个字符) |
| paste | 把多个文件按行并排拼接 | paste a.txt b.txt;paste -d, a b(指定分隔符) |
| join | 按公共字段连接两个已排序文件,类似 SQL 的 JOIN | join -t, -1 1 -2 1 a.csv b.csv |
| sort | 排序 | sort file;sort -n(按数值);sort -r(倒序);sort -k2(按第 2 列);sort -u(排序并去重);sort -t, -k2(指定分隔符) |
| uniq | 去重(只处理相邻重复行,所以通常先 sort) | sort file | uniq -c(计数,最常用组合);uniq -d(只显示重复行);uniq -u(只显示唯一行) |
| comm | 比较两个已排序文件,输出三列:仅在 A、仅在 B、共有 | comm a.txt b.txt;comm -12 a b(只显示共有行,即交集);comm -23 a b(只在 a 中) |
| wc | 统计行数/词数/字节数 | wc -l file(行数);wc -w(词数);wc -c(字节);wc -L(最长行长度) |
| tr | 字符级替换或删除,只处理单字符,不能替换字符串 | echo abc | tr 'a-z' 'A-Z'(转大写);tr -d '\r' < win.txt(去 CR);tr -s ' '(压缩连续空格) |
| fold | 按指定宽度折行 | fold -w 80 file;fold -s -w 80(在空格处断,不截断单词) |
| fmt | 重新排版段落,让每行长度均匀,写文本文件时有用 | fmt -w 80 file;fmt -u(统一空白) |
| expand / unexpand | 把 Tab 展开成空格 / 把空格转回 Tab | expand -t 4 file(Tab 按 4 列展开);unexpand -t 4 file |
| sed | 流编辑器,逐行处理,主力是替换与删除 | sed 's/old/new/g' file(全局替换);sed -i.bak 's/a/b/' file(原地修改并备份);sed -n '10,20p'(只打印 10-20 行);sed '/^#/d'(删注释行);sed -n '/start/,/end/p'(按范围打印) |
| awk | 按字段处理并可编程,做统计报表的主力 | awk '{print $1}' file;awk -F: '{print $1,$3}' /etc/passwd(指定分隔符);awk 'NR>1 {sum+=$3} END {print sum/NR}'(跳过表头求均值);awk '$3 > 100 {print $1}'(条件过滤);awk '{a[$1]++} END {for (k in a) print k, a[k]}'(按列分组计数) |
awk 的几个内置变量要记住:
$0是整行,$1~$n是各字段,NF是字段数,NR是当前行号,$NF是最后一个字段。日常最高频的用法是"取某一列"和"按某列分组计数"——后者用awk '{a[$1]++} END {for(k in a) print k, a[k]}'一行就能替代一段脚本。注意sed -i在 macOS 上必须写成sed -i '',Linux 上不需要。
四、合并、拆分与管道
管道(|)是 Unix 哲学的核心:每个命令只做好一件事,用管道串起来解决复杂问题。这一节的命令大多是管道的粘合剂——xargs 把标准输入转成命令参数,tee 让数据同时流向屏幕和文件。
| 命令 | 作用 | 常用示例 |
|---|---|---|
| diff | 逐行比较两个文件的差异 | diff a.txt b.txt;diff -u a b(unified 格式,生成补丁用);diff -r dir1 dir2(递归比较目录);diff -q(只报是否相同) |
| cmp | 逐字节比较,找到第一处不同就停,比 diff 快 | cmp a b && echo same;cmp -l a b(列出所有不同字节) |
| split | 把大文件拆成多个小文件 | split -l 1000 big.log part_(每 1000 行);split -b 100M big.tar part_(按大小);split -n 5 big(分成 5 份) |
| csplit | 按内容模式拆分文件(按"出现某行就切一刀") | csplit -f part_ log.txt '/ERROR/+1' '{*}'(每遇到 ERROR 切一段) |
| tee | 数据分流:一边输出到屏幕,一边写文件 | cmd | tee out.log;cmd | tee -a out.log(追加);cmd | sudo tee /etc/config(写入需要 root 的文件) |
| xargs | 把标准输入转换成命令行参数 | find . -name "*.log" | xargs grep error;xargs -n1(每次只传 1 个参数);xargs -I{} cp {} /backup/(占位符);find . -print0 | xargs -0 rm(正确处理含空格的文件名) |
| column | 把输入按列对齐成表格 | column -t -s: /etc/passwd;mount | column -t |
| pr | 给文本加页眉页脚并分栏,格式化打印用 | pr -2 file(两栏);pr -l 60 -h "标题" file |
xargs 的经典坑:文件名里有空格时会被拆成两个参数,导致 rm 报错或误删。解决办法是全程用
\0分隔——find ... -print0 | xargs -0 ...。另外cmd | sudo tee file是个实用技巧:sudo echo x > file不行(重定向由 shell 执行,没有 root 权限),但走 tee 就可以了。
五、编码与转换
文本处理里最阴魂不散的问题是编码和换行符。Windows 用 CRLF(\r\n),Linux 用 LF(\n);中文文件可能是 GBK 而非 UTF-8。这两类问题都表现为"看起来正常的文本,程序却处理出错",而且从屏幕上完全看不出来。
| 命令 | 作用 | 常用示例 |
|---|---|---|
od | 八进制/十六进制转储,看文件的原始字节 | od -c file(按字符显示,能看见 \r \n);od -tx1 file(十六进制字节) |
hexdump | 十六进制查看,比 od 更易读 | hexdump -C file(十六进制+ASCII 双栏);hexdump -C -n 64 file(只看前 64 字节) |
xxd | 十六进制转储,也可反向还原,编辑二进制时用 | xxd file | head;xxd -r hex.txt > binary(还原) |
| base64 | Base64 编码与解码,传输二进制或嵌入配置常用 | echo hello | base64;echo aGVsbG8= | base64 -d(解码);base64 -w 0 file(不换行) |
| iconv | 字符编码转换,解决中文乱码 | iconv -f GBK -t UTF-8 gbk.txt > utf8.txt;iconv -l(列出支持的编码);iconv -c(忽略无法转换的字符) |
dos2unix / unix2dos | 在 Windows(CRLF) 与 Unix(LF) 换行符之间转换 | dos2unix file(CRLF 转 LF);unix2dos file(反向);dos2unix -k(保留原时间戳) |
uuencode / uudecode | 古老的二进制编码传输方式,现在很少用但偶遇旧系统仍需要 | uuencode file name > out.uu;uudecode out.uu |
脚本报
\r: command not found或bad interpreter: /bin/bash^M,百分百是文件带着 Windows 换行符。用cat -A file | head -1能看到行尾的^M,确认后 dos2unix 一下即可。编码问题则先用file -i file看它声明的编码,再 iconv 转换。
一句话总结
文本处理速查:看日志用 tail -F/less/grep,改文本用 sed,取列与统计用 awk,排序去重用 sort | uniq -c,比对用 diff/comm,拆分用 split/csplit,串联用 |/xargs/tee,编码问题找 iconv/dos2unix——36 个命令是日志分析与数据加工的骨干,管道一搭,很多事不用写脚本。