bash中awk如何切分输出

在Bash中,使用`awk`切分输出有多种方式。

这里示例几种常见的使用方法。

1 基本字段切割

1.1 按空格/制表符分隔

显示第一列

echo "apple banana cherry" | awk '{print $1}'

显示第一列和第三列

echo "apple banana cherry date" | awk '{print 1, 3}'

显示最后一列

echo "apple banana cherry" | awk '{print $NF}'

显示倒数第二列

echo "apple banana cherry date" | awk '{print $(NF-1)}'

1.2 指定分隔符

使用 -F 指定分隔符

echo "apple,banana,cherry" | awk -F',' '{print $2}'

多个分隔符(正则表达式)

echo "apple;banana:cherry" | awk -F'[;:]' '{print 1, 3}'

输出时指定分隔符(OFS)

echo "apple banana cherry" | awk 'BEGIN{OFS=":"} {print 1, 2, $3}'

2 按列宽切割

即按固定宽度切割

复制代码
# 使用 substr 函数
echo "12345ABCDE" | awk '{print substr($0, 1, 5), substr($0, 6, 5)}'

# 更复杂的例子
data="20240101文件1.txt"
echo $data | awk '{
    date = substr($0, 1, 8)
    name = substr($0, 9)
    print "日期:", date, "文件名:", name
}'

3 处理复杂文本

复制代码
# 示例文本
cat <<EOF > data.txt
John:Doe:25:New York
Jane:Smith:30:Los Angeles
Bob:Johnson:35:Chicago
EOF

# 按冒号分隔,重新格式化输出
awk -F':' '{print "姓名:", $1, $2, "年龄:", $3, "城市:", $4}' data.txt

# 条件筛选 + 切割
awk -F':' '$3 > 30 {print $1 " is older than 30"}' data.txt

输出示例如下所示

姓名: John Doe 年龄: 25 城市: New York

姓名: Jane Smith 年龄: 30 城市: Los Angeles

姓名: Bob Johnson 年龄: 35 城市: Chicago

Bob is older than 30

4 高级切割技巧

复制代码
# 跳过前N行
ls -la | awk 'NR > 3 {print $9}'

# 使用正则表达式匹配分隔
echo "apple-123-orange-456" | awk '{split($0, a, /[0-9]+/); print a[1], a[2]}'

# 多字段重新组合
echo "2023-12-25" | awk -F'-' '{print "年月日:", $3"/"$2"/"$1}'

5 常用实际案例

5.1 分析系统进程

复制代码
# 获取前5个内存使用最多的进程
ps aux | sort -rnk 4 | head -5 | awk '{print "进程:", $11, "内存:", $4"%"}'

5.2 分析日志文件

复制代码
# 统计IP访问次数
cat access.log | awk '{print $1}' | sort | uniq -c | sort -rn

5.3 CSV文件处理

复制代码
# 处理CSV文件
awk -F',' 'BEGIN {OFS="\t"} {print $1, $3, $5}' data.csv

5.4 提取特定模式

复制代码
# 提取email地址
echo "联系我: test@example.com 或 admin@site.org" | \
awk '{ 
    for(i=1; i<=NF; i++) 
        if($i ~ /@/) 
            print "Email found:", $i 
}'

6 使用内置变量

复制代码
# NF: 字段数
echo "a b c d e" | awk '{print "字段数:", NF}'

# NR: 行号
awk '{print "行号", NR, ":", $0}' data.txt

# FS: 输入字段分隔符
# OFS: 输出字段分隔符
awk 'BEGIN{FS=":"; OFS="|"} {print $1, $3}' data.txt

7 一行命令实用例子

复制代码
# 获取磁盘使用率
df -h | awk '/\/dev\/sd/ {print "磁盘", $1, "使用率:", $5}'

# 计算文件总大小
ls -l *.txt | awk '{sum += $5} END {print "总大小:", sum/1024, "KB"}'

# 提取URL域名
echo "https://www.example.com/path" | awk -F'/' '{print $3}'

8 结合其他命令使用

复制代码
# 与 cut 对比(awk更灵活)
echo "a:b:c:d" | cut -d':' -f2      # 使用cut
echo "a:b:c:d" | awk -F':' '{print $2}'  # 使用awk

# 与 sed 结合
echo "name=value;age=30" | sed 's/;/\n/g' | awk -F'=' '{print $1}'

需要注意的是,在使用awk时,

使用 `-F` 指定输入分隔符

使用 `OFS` 控制输出分隔符

`0\` 表示整行,\`1`、`$2` 等表示各字段

`NF` 是字段总数,`NR` 是当前行号

可以使用正则表达式作为分隔符

简单列提取用`awk`默认空格分隔,固定宽度用`substr`,复杂分隔用`-F`指定分隔符。

reference


相关推荐
richard_yuu1 天前
C#零基础通关第六篇:吃透静态、常量与只读,分清静态与实例的本质差异
开发语言·c#
拂拉氏1 天前
【项目分享-知识讲解】C++标准库string类的模拟实现+KMP算法讲解+哈希思想了解
开发语言·c++·算法·kmp算法·哈希·string类
枫叶丹41 天前
【HarmonyOS 6.0】Graphics Accelerate Kit:AI超帧能力技术解析与实践
开发语言·人工智能·华为·harmonyos
HelloAldis1 天前
Java 库 univer-lib:让 Univer Sheets 与 xlsx 无损双向转换
java·开发语言·xlsx·univer
枕星而眠1 天前
C++ 类与对象核心知识点及面试高频题详解
开发语言·c++·面试
2501_930707781 天前
使用C#代码在 PowerPoint 中组合或取消组合形状
开发语言·c#
晚烛1 天前
CANN 调试工具与性能剖析:从日志分析到 NPU 行为追踪的完整调试体系
开发语言·windows·python·深度学习·缓存
惊鸿一博1 天前
图标加载方式_zeroIcon_是否加前缀mdi
开发语言·前端·javascript
森G1 天前
TypeScript 基础类型
开发语言·typescript
huipeng9261 天前
企业级微服务开发实战(一):项目启动与工程化设计
java·开发语言·spring boot·spring cloud·微服务·云原生·架构