脚本中Cut截取字段有哪些用法

wen 实用脚本 4

本文目录导读:

脚本中Cut截取字段有哪些用法

  1. 按字符位置截取 (-c)
  2. 按字节数截取 (-b)
  3. 按分隔符截取字段 (-d-f) —— 最常用
  4. 常用选项组合与技巧
  5. cutawk 的对比
  6. 脚本中的实际应用示例
  7. 总结:cut 的核心三要素

在Shell脚本(特别是Bash)中,cut 命令是一个非常常用的文本处理工具,主要用于从文件的每一行中截取指定字段字符

以下是 cut 截取字段的主要用法,按分隔方式分类:

按字符位置截取 (-c)

这是最基础的用法,按字符的绝对位置(从1开始计数)进行切割。

  • 语法: cut -c [位置]
  • 示例:
    echo "Hello World" | cut -c 1-5    # 输出:Hello (第1到第5个字符)
    echo "Hello World" | cut -c 7-11   # 输出:World (第7到第11个字符)
    echo "Hello World" | cut -c 1,3,5  # 输出:Hlo (第1、3、5个字符)
    echo "Hello World" | cut -c 3-     # 输出:llo World (第3个字符到末尾)
    echo "Hello World" | cut -c -5     # 输出:Hello (从开头到第5个字符)

按字节数截取 (-b)

功能与 -c 类似,但按字节计数,对于纯英文文本,-c-b 结果相同;对于包含中文字符的文本(UTF-8下每个汉字占3字节),使用 -b 要注意乱码。

  • 语法: cut -b [位置]
  • 示例:
    echo "abc123" | cut -b 1-3   # 输出:abc

按分隔符截取字段 (-d-f) —— 最常用

这是脚本中最强大的用法,用于处理结构化文本(如CSV、日志、/etc/passwd)。

  • 语法: cut -d '分隔符' -f [字段编号]

  • 参数:

    • -d:指定字段分隔符(默认是Tab键 \t)。
    • -f:指定要提取的字段列表。
  • 示例:

    # 1. 提取 /etc/passwd 中的用户名(以冒号分隔,第1列)
    cut -d ':' -f 1 /etc/passwd
    # 2. 提取日志中的IP和时间(空格分隔)
    echo "192.168.1.1 - - [10/Oct/2023] GET /index.html" | cut -d ' ' -f 1,4
    # 输出:192.168.1.1 [10/Oct/2023]
    # 3. 提取CSV的第2和第4列(逗号分隔)
    echo "ID,Name,Age,City" | cut -d ',' -f 2,4
    # 输出:Name,City
    # 4. 提取第3个字段及其之后的所有字段
    echo "a|b|c|d|e" | cut -d '|' -f 3-
    # 输出:c|d|e
    # 5. 指定补集(不显示第2个字段)
    echo "a b c d" | cut -d ' ' -f 1,3-  # 等效于 --complement -f2
    # 输出(假设用空格分隔):a c d

常用选项组合与技巧

a. 处理非固定分隔符(多空格)

cut 无法像 awk 那样自动处理多个连续空格,如果需要处理这种场景,可以先用 tr 压缩空格:

echo "John    Doe    30" | tr -s ' ' | cut -d ' ' -f 2
# 输出:Doe

b. 排除指定字段 (--complement)

-b, -c, -f 都可与此选项搭配,表示“显示除了指定字段以外的内容”。

echo "1:2:3:4:5" | cut -d ':' -f 1,2 --complement
# 输出:3:4:5 (即排除了第1、2列)

c. 处理没有分隔符的行

如果某行没有指定的分隔符,cut 默认会输出整行,可以用 -s 选项禁止输出:

echo -e "hello:world\nno_sep_line" | cut -d ':' -f 1 -s
# 输出:hello (第二行没有冒号,被忽略)

cutawk 的对比

特性 cut awk
分隔符 只能指定 单个 固定字符 支持 正则表达式 (如多个空格)
性能 非常快(适合简单提取) 较慢(但功能强大)
字段处理 只能提取,不能修改/新增 可重新排列、格式化、计算
多空格 需要 tr -s 配合 默认 awk 忽略多个空格
字符截取 -c 非常直接 需用 substr() 函数

选择建议:

  • 简单的列提取(定界符明确) → 用 cut(更快、语法更简洁)
  • 需要处理复杂分隔符、计算、条件过滤 → 用 awk

脚本中的实际应用示例

#!/bin/bash
# 1. 读取 /etc/passwd 检查用户 shell
USERS=$(cut -d: -f1,7 /etc/passwd)
echo "用户及其Shell:"
echo "$USERS"
# 2. 从日志提取每秒的请求数量
cat access.log | cut -d ' ' -f 4 | tr -d '[' | sort | uniq -c
# 3. 只显示非注释的配置文件内容(去掉注释行)
grep -v '^#' config.conf | cut -d '=' -f 1   # 只提取变量名
# 4. 提取网卡IP(ifconfig 示例)
ifconfig eth0 | grep "inet " | cut -d ' ' -f 12 | cut -d ':' -f 2

cut 的核心三要素

  1. -c(字符):处理固定宽度文本(如日志头部、密码字段)。
  2. -b(字节):处理二进制或按字节对齐的数据。
  3. -d + -f(分隔符+字段):处理结构化文本的标准化操作(如CSV、配置文件)。

常见坑点:

  • 默认分隔符是 Tab,处理空格时务必指定 -d ' '
  • 字段编号从 1 开始。
  • 不支持正则表达式作为分隔符(如需,用 awksed)。

抱歉,评论功能暂时关闭!