linux cut命令

命令简介

cut 命令用于从文件或标准输入中截取指定的字段、字符或字节。它是Linux文本处理工具链中的重要成员,常用于日志分析、数据提取和文本格式转换等场景。

语法

cut [选项] [文件]

常用形式:

# 按字段截取
cut -d 分隔符 -f 字段列表 [文件]

# 按字符截取
cut -c 字符位置列表 [文件]

# 按字节截取
cut -b 字节位置列表 [文件]

常用选项

选项 说明
-f, --fields=列表 指定要提取的字段列表
-d, --delimiter=分隔符 指定字段分隔符(默认是TAB)
-c, --characters=列表 指定要提取的字符位置
-b, --bytes=列表 指定要提取的字节位置
-s, --only-delimited 不显示没有分隔符的行
--complement 补集选择,显示未被选中的部分
--output-delimiter=字符串 指定输出分隔符

位置列表语法

语法 说明 示例
N 第N个字段/字符/字节 -f 3(第3个字段)
N- 从第N个到最后一个 -f 3-(第3个及以后所有字段)
N-M 从第N个到第M个 -f 2-5(第2到第5个字段)
-M 从第1个到第M个 -f -3(前3个字段)
N,M 第N个和第M个 -f 1,3(第1和第3个字段)

基本用法

1. 按字段截取(使用分隔符)
# 创建测试文件
echo -e "John:Doe:25:Engineer\nJane:Smith:30:Designer" > data.txt

# 提取第一个字段(姓名)
cut -d ':' -f 1 data.txt
# 输出:
# John
# Jane

# 提取第一个和第三个字段
cut -d ':' -f 1,3 data.txt
# 输出:
# John:25
# Jane:30

# 提取第二个到最后一个字段
cut -d ':' -f 2- data.txt
# 输出:
# Doe:25:Engineer
# Smith:30:Designer
2. 按字符位置截取
# 创建测试文件
echo -e "1234567890\nABCDEFGHIJ" > chars.txt

# 提取第1-5个字符
cut -c 1-5 chars.txt
# 输出:
# 12345
# ABCDE

# 提取第3个和第7-9个字符
cut -c 3,7-9 chars.txt
# 输出:
# 3789
# CEFG
3. 按字节截取
# 对于ASCII文本,字节和字符通常相同
echo -e "hello\nworld" > bytes.txt
cut -b 1-3 bytes.txt
# 输出:
# hel
# wor
4. 使用补集选择
# 提取除第一个字段外的所有字段
echo -e "apple:banana:cherry:date" | cut -d ':' -f 2- --complement
# 输出:
# apple

# 提取除第2-4个字符外的所有字符
echo "1234567890" | cut -c 2-4 --complement
# 输出:
# 1567890

实际应用场景

场景1:日志文件分析
# 分析Apache访问日志,提取IP地址和状态码
cat access.log | cut -d ' ' -f 1,9
# 示例输出:
# 192.168.1.100 200
# 192.168.1.101 404

# 提取时间戳和请求方法
cat access.log | cut -d ' ' -f 4,6
# 示例输出:
# [10/Oct/2023:14:30:01 "GET
# [10/Oct/2023:14:30:02 "POST
场景2:系统信息提取
# 提取/etc/passwd中的用户名和shell
cut -d ':' -f 1,7 /etc/passwd
# 示例输出:
# root:/bin/bash
# daemon:/usr/sbin/nologin

# 提取当前登录用户
who | cut -d ' ' -f 1
# 输出当前登录的所有用户名

# 提取磁盘使用率百分比
df -h | cut -d '%' -f 1 | cut -d ' ' -f 1-
场景3:CSV文件处理
# 处理CSV文件,提取特定列
echo -e "Name,Age,Salary,Department\nJohn,25,50000,IT\nJane,30,60000,HR" > employees.csv

# 提取姓名和部门
cut -d ',' -f 1,4 employees.csv
# 输出:
# Name,Department
# John,IT
# Jane,HR

# 提取除薪资外的所有信息
cut -d ',' -f 3 --complement employees.csv
# 输出:
# Name,Age,Department
# John,25,IT
# Jane,30,HR
场景4:固定宽度文件处理
# 处理固定宽度的数据文件
echo -e "001John Doe   25\n002Jane Smith 30" > fixed_width.txt

# 提取ID(位置1-3)
cut -c 1-3 fixed_width.txt
# 输出:
# 001
# 002

# 提取姓名(位置4-13)和年龄(位置14-15)
cut -c 4-13,14-15 fixed_width.txt
# 输出:
# John Doe   25
# Jane Smith 30

高级用法

1. 与其他命令组合使用
# 提取进程ID并杀死进程
ps aux | grep "nginx" | grep -v grep | cut -c 10-15 | xargs kill

# 提取文件大小并排序
ls -l | cut -d ' ' -f 5 | sort -n

# 提取URL中的域名
echo "https://www.example.com/path/to/page" | cut -d '/' -f 3
# 输出:www.example.com
2. 处理多字节字符
# 对于包含多字节字符(如中文)的文件
echo "你好世界 hello 世界" > multibyte.txt

# 使用字符截取(推荐)
cut -c 1-3 multibyte.txt
# 输出:你好世

# 使用字节截取可能得到不完整字符(不推荐)
cut -b 1-6 multibyte.txt
# 可能输出乱码
3. 自定义输出分隔符
# 改变输出字段的分隔符
echo "apple:banana:cherry" | cut -d ':' -f 1,3 --output-delimiter=' -> '
# 输出:apple -> cherry

# 使用管道符号分隔
cut -d ':' -f 1,2 /etc/passwd --output-delimiter=' | '
4. 在脚本中使用
#!/bin/bash
# 处理配置文件
CONFIG_FILE="app.conf"

# 提取配置值
get_config() {
    local key=$1
    grep "^$key=" "$CONFIG_FILE" | cut -d '=' -f 2-
}

# 使用函数
DB_HOST=$(get_config "database.host")
DB_PORT=$(get_config "database.port")

echo "数据库连接: $DB_HOST:$DB_PORT"

# 处理多行数据
process_data() {
    while IFS= read -r line; do
        username=$(echo "$line" | cut -d ':' -f 1)
        uid=$(echo "$line" | cut -d ':' -f 3)
        echo "用户 $username 的UID是 $uid"
    done < /etc/passwd
}

与其他命令的比较

命令 特点 适用场景
cut 按位置或分隔符提取,简单高效 固定格式文本、日志文件、CSV数据
awk 功能强大,支持编程 复杂文本处理、数据计算、条件过滤
sed 流编辑器,支持正则表达式 文本替换、删除、插入等编辑操作
grep 模式匹配,过滤行 搜索特定模式、过滤文本行

注意事项

  • 默认字段分隔符是TAB,不是空格
  • 使用-d选项时,分隔符只能是单个字符
  • 对于包含多字节字符的文本,使用-c而不是-b
  • cut不能重新排列字段顺序,只能按原顺序选择
  • 使用-s选项可以过滤掉不包含分隔符的行
  • 位置编号从1开始,不是0
  • 对于复杂的数据处理,考虑使用awk命令