cut命令详解

cut 是一个用于从文件或标准输入中提取文本列的命令行工具,主要用于按列截取文本数据。

基本语法

bash 复制代码
cut OPTION... [FILE]...

主要选项分类

1. 按字节选择 (-b)

bash 复制代码
# 提取第1个字节
echo "abcdef" | cut -b 1          # 输出: a

# 提取第1,3,5个字节
echo "abcdef" | cut -b 1,3,5      # 输出: ace

# 提取1-3字节
echo "abcdef" | cut -b 1-3        # 输出: abc

# 提取第3个字节到行尾
echo "abcdef" | cut -b 3-         # 输出: cdef

# 提取行首到第4个字节
echo "abcdef" | cut -b -4         # 输出: abcd

# 混合范围
echo "abcdef" | cut -b 1-3,5-     # 输出: abcef

2. 按字符选择 (-c)

bash 复制代码
# 提取单个字符
echo "hello" | cut -c 1           # 输出: h

# 提取字符范围
echo "hello world" | cut -c 1-5   # 输出: hello

# 注意:对于多字节字符(如中文)要小心
echo "你好世界" | cut -c 1-2      # 可能输出异常,因为中文字符占多个字节

3. 按字段选择 (-f)

bash 复制代码
# 默认以TAB为分隔符,提取第1个字段
echo -e "a\tb\tc" | cut -f 1      # 输出: a

# 指定分隔符提取字段
echo "a,b,c" | cut -d ',' -f 1    # 输出: a

# 提取多个字段
echo "a,b,c,d,e" | cut -d ',' -f 1,3,5  # 输出: a,c,e

# 提取字段范围
echo "a,b,c,d,e" | cut -d ',' -f 2-4    # 输出: b,c,d

常用参数详解

-d, --delimiter=DELIM

指定字段分隔符

bash 复制代码
# 使用冒号分隔
echo "root:x:0:0:root:/root:/bin/bash" | cut -d ':' -f 1,6
# 输出: root:/root

# 使用空格分隔(注意引号)
echo "John Smith 25" | cut -d ' ' -f 1,3
# 输出: John 25

--complement

补集选择(选择未指定的部分)

bash 复制代码
# 除了第1个字段,其他都显示
echo "a,b,c,d" | cut -d ',' -f 1 --complement
# 输出: b,c,d

# 除了1-3字节
echo "abcdef" | cut -b 1-3 --complement
# 输出: def

-s, --only-delimited

只显示包含分隔符的行

bash 复制代码
# 假设文件内容:
# line1: a,b,c
# line2: no delimiter
# line3: x,y,z

cut -d ',' -f 1 -s file.txt
# 只输出有逗号的行: line1和line3的第一个字段

--output-delimiter=STRING

指定输出分隔符

bash 复制代码
# 使用分号作为输出分隔符
echo "a,b,c,d" | cut -d ',' -f 1-4 --output-delimiter=';'
# 输出: a;b;c;d

# 输入是冒号分隔,输出改为空格分隔
echo "root:x:0:0" | cut -d ':' -f 1,3,4 --output-delimiter=' '
# 输出: root 0 0

实用示例

1. 处理系统文件

bash 复制代码
# 从/etc/passwd提取用户名和shell
cut -d ':' -f 1,7 /etc/passwd

# 查看所有用户
cut -d ':' -f 1 /etc/passwd

2. 处理CSV文件

bash 复制代码
# data.csv内容:
# id,name,age,city
# 1,John,25,NY
# 2,Jane,30,LA

# 提取姓名和城市
cut -d ',' -f 2,4 data.csv

3. 处理日志文件

bash 复制代码
# 提取IP地址(假设IP在第1列,空格分隔)
cut -d ' ' -f 1 access.log

# 提取特定时间范围
cut -d ' ' -f 4 access.log | cut -d ':' -f 1,2

4. 处理命令输出

bash 复制代码
# 获取当前目录下文件名(ls -l第一列是权限)
ls -l | cut -d ' ' -f 9

# 获取进程PID
ps aux | grep nginx | cut -d ' ' -f 2

5. 与其他命令组合

bash 复制代码
# 统计每个IP的访问次数
cut -d ' ' -f 1 access.log | sort | uniq -c

# 提取CPU使用率
top -b -n 1 | grep "Cpu(s)" | cut -d ',' -f 1 | cut -d ':' -f 2

# 提取文件名和扩展名
echo "document.txt" | cut -d '.' -f 1      # 文件名: document
echo "document.txt" | cut -d '.' -f 2      # 扩展名: txt

高级技巧

1. 处理固定宽度文件

bash 复制代码
# 假设数据是固定宽度排列
# 001John   25NY
# 002Jane   30LA

# 使用-c按字符位置提取
cut -c 1-3,4-8,9-10,11-12 data.txt

2. 多重分隔符处理

bash 复制代码
# 虽然cut不支持正则表达式分隔符,但可以配合tr使用
echo "a;b,c|d" | tr ',;|' '\t' | cut -f 2

3. 排除空字段

bash 复制代码
# 过滤掉空行或空字段
echo -e "a,b\n,c\nd,e," | cut -d ',' -f 2 | grep -v '^$'

注意事项和限制

不支持正则表达式分隔符

bash 复制代码
# 错误:不能使用正则
cut -d '[ ,;]' -f 1 file.txt  # 不会按预期工作

处理中文等宽字符问题

bash 复制代码
# 对于UTF-8编码的中文,每个字符占3个字节
echo "你好" | cut -b 1-3      # 输出: 你
echo "你好" | cut -c 1        # 输出: 你

与awk的区别

  • cut:简单快速,适合简单的列提取

  • awk:功能强大,支持复杂处理、计算和条件判断

常见错误解决

bash 复制代码
# 错误:分隔符是多个空格时
echo "John  Smith  25" | cut -d ' ' -f 2  # 输出为空

# 正确:先压缩空格
echo "John  Smith  25" | tr -s ' ' | cut -d ' ' -f 2  # 输出: Smith

# 错误:字段编号超出范围时不报错
echo "a,b" | cut -d ',' -f 1,5  # 输出: a(不报错)

# 错误:空分隔符
echo "abc" | cut -d '' -f 1      # 错误:分隔符不能为空

总结

cut 命令是一个高效简单的文本处理工具,特别适合:

  • 处理结构化文本数据

  • 从日志文件中提取特定字段

  • 快速查看文件的特定列

  • 与其他命令组合进行数据处理

对于更复杂的文本处理需求(如正则表达式、条件判断、计算等),建议使用 awksed

相关推荐
chlk1238 小时前
Linux文件权限完全图解:读懂 ls -l 和 chmod 755 背后的秘密
linux·操作系统
舒一笑8 小时前
Ubuntu系统安装CodeX出现问题
linux·后端
改一下配置文件9 小时前
Ubuntu24.04安装NVIDIA驱动完整指南(含Secure Boot解决方案)
linux
深紫色的三北六号18 小时前
Linux 服务器磁盘扩容与目录迁移:rsync + bind mount 实现服务无感迁移(无需修改配置)
linux·扩容·服务迁移
SudosuBash1 天前
[CS:APP 3e] 关于对 第 12 章 读/写者的一点思考和题解 (作业 12.19,12.20,12.21)
linux·并发·操作系统(os)
哈基咪怎么可能是AI1 天前
为什么我就想要「线性历史 + Signed Commits」GitHub 却把我当猴耍 🤬🎙️
linux·github
十日十行2 天前
Linux和window共享文件夹
linux
木心月转码ing2 天前
WSL+Cpp开发环境配置
linux
崔小汤呀3 天前
最全的docker安装笔记,包含CentOS和Ubuntu
linux·后端
何中应3 天前
vi编辑器使用
linux·后端·操作系统