cut -c 按字符位置截取,索引从1开始,支持单个位置(如-c 5)、范围(如-c 3-7)及组合(如-c 3,7),但需注意utf-8中文可能因locale设置不当被拆分导致乱码。

cut -c 按字符位置截取最直接
想精确取第 5 个字符、或第 3–7 个字符,cut -c 是首选。它不关心分隔符,纯按字节(ASCII)或 Unicode 字符位置算——但注意:中文等多字节字符在 UTF-8 下可能被拆断,实际效果取决于 locale 设置。
常见错误是以为 cut -c 2-5 包含空格后第 2 位,结果发现开头有空格没跳过。实际就是从字符串首字符开始数,索引从 1 起(不是 0)。
-
echo "hello world" | cut -c 1-5→ 输出hello -
echo "apple" | cut -c 3→ 输出p -
echo "a b c" | cut -c 3,5→ 输出(第 3 位空格 + 第 5 位空格)
cut -d -f 按分隔符切字段,不是按“位”
很多人搜“截取第几位”却误用 -f,结果出错。这个组合只适用于字段(field)场景,比如 CSV 或空格分隔的单词。它先按 -d 指定分隔符切开,再取第几个字段。
典型陷阱:cut -d' ' -f 2 不等于“第二个字符”,而是“第二个由空格隔开的字段”。如果输入是 a bb c(多个空格),-f 2 取到的是 bb,不是第 2 个字符 。
-
echo "name:age:city" | cut -d':' -f 2→ 输出age -
echo "foo bar baz" | cut -d' ' -f 1,3→ 输出foo baz - 若字段含空格又想保留,
cut无能为力,得换awk或sed
中文或 UTF-8 字符串慎用 cut -c
cut 默认按字节操作,而 UTF-8 中一个中文字符占 3 字节。执行 cut -c 2-4 可能切在某个汉字中间,输出乱码(如 )或缺失。
解决办法只有两个:要么确保终端 locale 是 UTF-8(locale | grep UTF 查看),此时 GNU coreutils 的 cut 通常能按字符处理;要么干脆别用 cut,改用 awk '{print substr($0,2,3)}' —— substr 在 gawk 下原生支持 Unicode 字符索引。
-
echo "你好世界" | LC_ALL=en_US.UTF-8 cut -c 2-3→ 正确输出好世 -
echo "你好世界" | cut -c 2-3(无 locale)→ 可能输出乱码或空 - 脚本中硬编码
LC_ALL=C会强制字节模式,和预期相反
替代方案:什么时候不该坚持用 cut
当需求变成“取第 n 个单词”“跳过前 m 个字符再取 k 个”“按正则边界切”,cut 就太单薄了。它没有变量、不支持条件、不能回溯。
简单对比:
- 取第 2 个单词(按空白):
awk '{print $2}'比cut -d' ' -f 2更稳(自动压缩连续空格) - 取从第 5 个字符起的 10 个字符:
cut -c 5-14行,但substr($0,5,10)在 awk 里更直观且 Unicode 安全 - 提取 JSON 字段值?别试
cut,用jq或至少sed配正则
cut 的价值在于简单、POSIX 兼容、无依赖,但一旦字符串结构稍复杂,它的“指定位”就容易失准。真正要靠位置截取时,优先确认字符编码,再决定是强设 locale 还是换工具。











