1. 先从一次“惨痛”的文本处理说起
我大概在刚接触 Linux 运维那会儿,遇到过这么一件事:线上有个服务日志,每天凌晨会往文件里追加将近两万行访问记录,格式是约定的 IP地址|访问时间|请求路径|状态码。当时要做一个快速统计,只需要把每行里的 IP 和状态码抽出来,老板催得急,我第一反应是写个 while read 循环再配 awk -F'|' '{print $1, $4}'。awk 确实能搞定,但那次脚本跑到一半,终端卡顿得厉害,处理完足足花了两分钟。
后来一位同事看了一眼,说了句:“你直接用 cut 不就行了?”我改成 cut -d'|' -f1,4,五秒钟不到就出结果了。从那天起,我才认真去研究 cut 这个命令。说真的,在 Linux 常用命令里,cut 就像工具箱里那把特别顺手的美工刀,功能范围不算广,但遇到需要按列切割文本的场景,在效率和简洁性上能吊打很多你原以为“更高级”的工具。
这篇文章不打算把 cut 的所有细节罗列成一本“手册”,而是按我实际工作中的使用路径来讲:先理解它的设计思路,再拆解三个工作模式和范围语法,然后放进几个真实场景里跑一遍,最后把踩过的坑和排查思路整理成速查表。无论你是刚开始学 Linux 的新人,还是用了好几年但仍然习惯性写 awk 的老手,这篇文章都能让你对 cut 有一个更系统的认识。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 理解 cut 的核心设计:它到底在“切”什么
2.1 cut 与 awk 的定位差异:为什么有时用 cut 更合适
很多教程在讲 cut 时喜欢直接列参数,但我建议大家先想清楚一个问题:awk 也能按分隔符取列,为什么还要用 cut?我的理解是,awk 是一个完整的“文本处理语言”,它有变量、判断、循环、内置函数,它是“武器库”;而 cut 是一个纯粹的“列提取器”,它不做运算,不搞状态管理,不读入内存再去逐行解析,它就是拿一个“行”进来,按照你指定的切法,原样输出需要的部分。
也正因为 kernel 底层实现得简单,cut 在处理超大型文件时优势非常明显。我自己做过一次粗略对比:从一个 500MB 左右的日志文件里提取某两列,awk -F',' '{print $1,$3}' 大概耗时 7.8 秒,而 cut -d',' -f1,3 耗时 3.2 秒。如果你需要在一台只分配了 2GB 内存的小机器上处理几个 GB 的文本,这种差距会直接决定任务能不能在当前环境下跑完。
所以我现在的选择标准很简单:如果只是“纯粹地按分隔符把第几列取出来”,优先 cut;如果还需要“对已取出的列做正则匹配、做数值比较、做统计求和”,那才上 awk。cut 也有自己的短板:它只能按分隔符、字符位置或字节位置来切,不能按“关键字”切。这一点我们到后面第 5 节专门讲,因为它恰恰是很多人踩坑的地方。
2.2 三个核心参数:-f、-c、-b 的本质区别
cut 的工作模式围绕三个参数展开:
-f(field):以字段为单位切割,核心前提是先通过-d指定分隔符。-c(character):以“字符”为单位切割,适合处理按固定宽度排列的文本。-b(byte):以“字节”为单位切割,能精准控制字节偏移,常用于处理二进制导出文件或严格按字节对齐的数据。
这三个参数本质上是三种不同的“标尺”。很多初学者会把 -c 和 -b 搞混,觉得“字符不就是字节吗”?在纯英文环境里确实一样,但一旦遇到中文,区别就大了。中文字符在 UTF-8 编码下通常占用 3 个字节,在 GBK 编码下占用 2 个字节。你如果知道目标文件是 UTF-8 编码,但数据前几列恰好是“一个汉字 + 几个字母”的混排,用 -c 1 可以正确取出那个汉子,用 -b 1 可能只会切出半个字符的输出,轻则乱码,重则导致后续程序解析崩溃。
我整理了一张对照表,方便大家快速理解:
| 参数 | 切割单位 | 典型场景 | 能否处理多字节字符 |
|---|---|---|---|
| -f | 字段(两两分隔符之间) | 处理 CSV、/etc/passwd、日志 | 能,与分隔符无关 |
| -c | 字符 | 固定宽度的文本排列 | 能,按语言编码取整字符 |
| -b | 字节 | 二进制数据、纯 ASCII 定长记录 | 不建议用于中文 |
这个表也是我在面试 Linux 候选人时最常问的一组概念,能把 -b 与 -c 的区别讲清楚,说明对底层字符编码是有概念的,而不只是背命
