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 命令是一个高效简单的文本处理工具,特别适合:
-
处理结构化文本数据
-
从日志文件中提取特定字段
-
快速查看文件的特定列
-
与其他命令组合进行数据处理
对于更复杂的文本处理需求(如正则表达式、条件判断、计算等),建议使用 awk 或 sed。