awk 和cut

# 组合多个字段
echo "luci-base - 2.5.0-1 - 2.5.1-1" | awk '{print $1 " 从 " $3 " 升级到 " $5}'
# 输出:luci-base 从 2.5.0-1 升级到 2.5.1-1

# 使用逗号分隔(AWK会自动添加空格)
echo "luci-base - 2.5.0-1 - 2.5.1-1" | awk '{print $1, "版本变化:", $3, "->", $5}'
# 输出:luci-base 版本变化: 2.5.0-1 -> 2.5.1-1

后者

# 显示字段数量
echo "one two three four five" | awk '{print "字段数:", NF}'
# 输出:字段数: 5

# 显示所有字段
echo "apple banana cherry" | awk '{print "第1个:", $1, "第2个:", $2, "第3个:", $3, "总共:", NF "个字段"}'
# 输出:第1个: apple 第2个: banana 第3个: cherry 总共: 3个字段

# 多行时显示行号
echo -e "第一行\n第二行\n第三行" | awk '{print "第" NR "行:", $0}'
# 输出:
# 第1行: 第一行
# 第2行: 第二行  
# 第3行: 第三行

计算

# 简单计算
echo "10 20 30" | awk '{print $1 + $2 + $3}'
# 输出:60

# 平均值计算
echo "10 20 30" | awk '{print "平均值:", ($1 + $2 + $3) / NF}'
# 输出:平均值: 20

# 字符串长度
echo "hello world" | awk '{print "第一个字段长度:", length($1)}'
# 输出:第一个字段长度: 5

好的!我用 echo 结合 cut 来演示 cut 的工作原理:
CUT 基本原理
cut 是一个列提取工具,按指定的分隔符或字符位置来切割文本。
基本语法
bashcut -d '分隔符' -f 字段号
cut -c 字符位置
字段分割演示(-f 参数)

  1. 基础字段提取
echo -e "apple\tbanana\tcherry" | cut -f 1

# 输出:apple

指定空格为分隔符,提取第1字段

echo "luci-base - 2.5.0-1 - 2.5.1-1" | cut -d ' ' -f 1
# 输出:luci-base

提取第3字段

echo "luci-base - 2.5.0-1 - 2.5.1-1" | cut -d ' ' -f 3
# 输出:2.5.0-1
  1. 多字段提取
bash# 提取第1和第3字段
echo "apple banana cherry date" | cut -d ' ' -f 1,3
# 输出:apple cherry

提取第1到第3字段

echo "apple banana cherry date" | cut -d ' ' -f 1-3
# 输出:apple banana cherry

提取第2字段到最后

echo "apple banana cherry date" | cut -d ' ' -f 2-
# 输出:banana cherry date
  1. 不同分隔符演示
bash# 逗号分隔
echo "张三,25,工程师,北京" | cut -d ',' -f 2
# 输出:25

冒号分隔

echo "user:password:1001:1001:User:/home/user:/bin/bash" | cut -d ':' -f 1,6
# 输出:user:/home/user

制表符分隔(默认)

echo -e "name\tage\tcity" | cut -f 2
# 输出:age

字符位置切割演示(-c 参数)

4. 按字符位置提取
bash# 提取第1个字符
echo "hello world" | cut -c 1
# 输出:h

提取第1-5个字符

echo "hello world" | cut -c 1-5
# 输出:hello

提取第7个字符到最后

echo "hello world" | cut -c 7-
# 输出:world

提取多个不连续位置

echo "hello world" | cut -c 1,3,5,7,9

# 输出:hlool
  1. 实际应用场景
bash# 提取IP地址的第一段
echo "192.168.1.100" | cut -d '.' -f 1
# 输出:192

提取文件扩展名

echo "document.pdf" | cut -d '.' -f 2
# 输出:pdf

提取日期的年份

echo "2024-03-15" | cut -d '-' -f 1
# 输出:2024

多行处理演示

  1. 批量处理多行
bash# 处理多行数据
echo -e "luci-base - 2.5.0-1 - 2.5.1-1\nkernel - 5.4.188-1 - 5.4.210-1\ndropbear - 2020.81-2 - 2022.82-1" | cut -d ' ' -f 1
# 输出:
# luci-base
# kernel
# dropbear

提取每行的第3和第5字段

echo -e "luci-base - 2.5.0-1 - 2.5.1-1\nkernel - 5.4.188-1 - 5.4.210-1" | cut -d ' ' -f 3,5
# 输出:
# 2.5.0-1 2.5.1-1
# 5.4.188-1 5.4.210-1

CUT 的限制演示

  1. 处理多个连续空格的问题
bash# 正常情况(单个空格)
echo "apple banana cherry" | cut -d ' ' -f 2
# 输出:banana

问题情况(多个空格)

echo "apple banana cherry" | cut -d ' ' -f 2

输出:(空)

为什么会这样?让我们看看各个字段:

echo "apple banana cherry" | cut -d ' ' -f 1

输出:apple

echo "apple banana cherry" | cut -d ' ' -f 2

输出:(空,因为第2个字段是空格)

echo "apple banana cherry" | cut -d ' ' -f 5

输出:banana(实际在第5个位置)

  1. 对比 CUT vs AWK 处理空格
    bash# 多个空格的情况
    text="apple banana cherry"

cut 的处理(有问题)

echo "$text" | cut -d ' ' -f 2

输出:(空)

awk 的处理(正常)

echo "text" | awk '{print2}'

输出:banana

解释 cut 为什么这样

echo "$text" | cut -d ' ' -f 1-10 --output-delimiter='|'

输出:apple||||banana||||cherry

可以看到多个连续空格被当作多个空字段

字节切割演示(-b 参数)

  1. 按字节位置
    bash# 提取前3个字节
    echo "hello" | cut -b 1-3

输出:hel

中文字符处理(UTF-8编码)

echo "你好世界" | cut -b 1-3

输出:你(中文字符占3字节)

echo "你好世界" | cut -c 1-2

输出:你好(按字符数)

实战应用演示

  1. 系统管理场景
    bash# 模拟处理 /etc/passwd 格式
    echo "root:x:0:0:root:/root:/bin/bash" | cut -d ':' -f 1,3

输出:root:0

处理CSV格式

echo "张三,28,工程师,50000,北京" | cut -d ',' -f 1,4

输出:张三,50000

提取MAC地址的厂商标识

echo "aa:bb:cc:dd:ee:ff" | cut -d ':' -f 1-3

输出:aa:bb:cc

  1. 对比原始的 opkg 命令
    bash# 模拟 opkg list-upgradable 输出
    opkg_output="luci-base - 2.5.0-1 - 2.5.1-1"

使用 cut 提取包名

echo "$opkg_output" | cut -d ' ' -f 1

输出:luci-base

使用 cut 提取当前版本

echo "$opkg_output" | cut -d ' ' -f 3
# 输出:2.5.0-1

使用 cut 提取新版本

echo "$opkg_output" | cut -d ' ' -f 5  
# 输出:2.5.1-1
  1. CUT 的优势和劣势
bash# 优势:简单直接,适合规整格式
echo "name,age,city" | cut -d ',' -f 2    # 简单清晰

劣势:不能处理不规整的空格

echo "name  age    city" | cut -d ' ' -f 2  # 得到空结果

相比之下 awk 更灵活

echo "name  age    city" | awk '{print $2}' # 得到 "age"

总结对比

bash# 数据示例
data="luci-base - 2.5.0-1 - 2.5.1-1"

cut: 严格按分隔符切割

echo "$data" | cut -d ' ' -f 1     # luci-base

awk: 智能处理空白字符

echo "$data" | awk '{print $1}'    # luci-base

cut 更适合:格式固定、分隔符明确的数据

awk 更适合:格式可能不规整、需要复杂处理的数据

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容