当前位置: 首页 > news >正文

Linux Shell awk

awk 是一个功能强大的文本处理工具,它不仅是 Linux 命令,更是一门专门的编程语言。
它特别擅长处理结构化文本数据(如日志、CSV文件等),
能够进行逐行扫描、字段分割、模式匹配和数据操作。

一、awk 基本概念和工作原理
1. 工作原理

awk 的基本工作流程是:逐行扫描文件,从第一行到最后一行。对于每一行,它会检查是否匹配指定的“模式”,如果匹配,则执行对应的“动作”。

2. 基本语法
awk '模式 { 动作 }' 输入文件
模式:可以是正则表达式、条件表达式(如 NR > 10)、特殊模式(BEGIN 或 END),或者完全省略(表示处理所有行)。

动作:是一系列用花括号 {} 括起来的命令,通常是 print 语句,多个命令之间用分号 ; 分隔。

输入文件:要处理的文本文件。如果不指定,则从标准输入读取

3. 内置变量

awk 预定义了许多有用的变量,无需声明即可使用。
变量名    含义
$0    当前行的全部内容
$1, $2, ... $n    当前行的第1个、第2个...第n个字段
NF    Number of Fields,当前行的字段总数
NR    Number of Records,当前的行号(对所有文件累计)
FNR    File Number of Records,当前文件中的行号
FS    Field Separator,输入字段分隔符(默认为空格/制表符)
OFS    Output Field Separator,输出字段分隔符(默认为空格)
RS    Record Separator,输入记录(行)分隔符(默认为换行符)
ORS    Output Record Separator,输出记录(行)分隔符(默认为换行符)
FILENAME    当前正在处理的文件名


二、awk 使用案例
假设我们有一个名为 students.txt 的文件,内容如下:

Alice Johnson 95 88 92
Bob Smith 78 85 80
Carol Davis 88 91 89
David Miller 65 70 75

案例1:基本打印
打印整个文件:
awk '{print}' students.txt
# 或
awk '{print $0}' students.txt
打印第一列(姓名):
awk '{print $1}' students.txt
[root@hadoop ~]# awk '{print $1}' students.txt
Alice
Bob
Carol
David
打印第一列和第三列:

[root@hadoop ~]# awk '{print $1, $3}' students.txt
Alice 95
Bob 78
Carol 88
David 65

案例2:使用 NF 和 NR
打印每一行的最后一个字段:

awk '{print $NF}' students.txt
# 输出:92 80 89 75

打印行号和该行的内容:
awk '{print NR, $0}' students.txt

[root@hadoop ~]# awk '{print NR, $0}' students.txt
1 Alice Johnson 95 88 92
2 Bob Smith 78 85 80
3 Carol Davis 88 91 89
4 David Miller 65 70 75

打印文件总行数:打印文件总行数:
[root@hadoop ~]# awk 'END {print NR}' students.txt
4
案例3:模式匹配(过滤)
打印包含 "Bob" 的行:
[root@hadoop ~]# awk '/Bob/ {print $0}' students.txt
Bob Smith 78 85 80

打印第二门课成绩大于90的行:
[root@hadoop ~]# awk '$4 > 90 {print $1, $4}' students.txt
Carol 91

打印第一门课成绩在80到100之间的行:
awk '$3 >= 80 && $3 <= 100 {print $0}' students.txt


[root@hadoop ~]# awk '$3 >= 80 && $3 <= 100 {print $0}' students.txt
Alice Johnson 95 88 92
Carol Davis 88 91 89

案例4:使用 BEGIN 和 END
BEGIN 和 END 是特殊的模式,分别在处理第一行之前和处理完最后一行之后执行。

添加表头:
[root@hadoop ~]# awk 'BEGIN {print "Name\tScore1\tScore2\tScore3"; print "----------------------"}
>      {print $1, $3, $4, $5}
>      END {print "----------------------\nProcessing complete."}' students.txt
Name    Score1  Score2  Score3
----------------------
Alice 95 88 92
Bob 78 85 80
Carol 88 91 89
David 65 70 75
----------------------
Processing complete.


案例5:字段分隔符
处理 CSV 文件(逗号分隔)
假设有 data.csv:
John,Doe,30
Jane,Smith,25

awk -F, '{print $1, $3}' data.csv
# -F, 指定输入字段分隔符为逗号
# 输出:
# John 30
# Jane 25
[root@hadoop ~]# awk -F, '{print $1, $3}' data.csv
John 30
Jane 25

同时指定输入和输出分隔符:
awk 'BEGIN {FS=" "; OFS=" - "} {print $1, $NF}' students.txt
[root@hadoop ~]# awk 'BEGIN {FS=" "; OFS=" - "} {print $1, $NF}' students.txt
Alice - 92
Bob - 80
Carol - 89
David - 75


案例6:计算和统计
计算每个学生的平均分:
awk '{sum = $3 + $4 + $5; avg = sum / 3; print $1, avg}' students.txt
# 输出:
# Alice 91.6667
# Bob 81
# Carol 89.3333
# David 70

[root@hadoop ~]# awk '{sum = $3 + $4 + $5; avg = sum / 3; print $1, avg}' students.txt
Alice 91.6667
Bob 81
Carol 89.3333
David 70

计算全班第一门课的总分和平均分:
awk '{sum += $3} END {print "Total: " sum, "Average: " sum/NR}' students.txt
# 输出:Total: 326 Average: 81.5

案例7:使用 if-else 语句
awk 也支持完整的编程结构。

给成绩评级:
awk '{
avg = ($3+$4+$5)/3;
if (avg >= 90) grade = "A";
else if (avg >= 80) grade = "B";
else if (avg >= 70) grade = "C";
else grade = "F";
print $1, avg, grade;
}' students.txt
# 输出:
# Alice 91.6667 A
# Bob 81 B
# Carol 89.3333 B
# David 70 C

案例8:字符串操作
连接姓和名:
awk '{name = $1 " " $2; print name}' students.txt
# 输出:
# Alice Johnson
# Bob Smith
# Carol Davis
# David Miller


查找名字长度大于4的学生:
awk 'length($1) > 4 {print $1}' students.txt

[root@hadoop ~]# awk 'length($1) > 4 {print $1}' students.txt
Alice
Carol
David

三、高级用法:awk 脚本
当命令变得复杂时,可以将其写入一个脚本文件(例如 process.awk)。

process.awk 文件内容:
#!/usr/bin/awk -f
# 这是一个awk脚本示例

BEGIN {
print "=== 学生成绩报告 ==="
printf "%-10s %-8s %s\n", "Name", "Average", "Grade"
print "------------------------"
total_sum = 0
}

{
sum = $3 + $4 + $5
avg = sum / 3
total_sum += avg

  if (avg >= 90) grade = "A"
else if (avg >= 80) grade = "B"
else if (avg >= 70) grade = "C"
else grade = "F"

  printf "%-10s %-8.2f %s\n", $1, avg, grade
}

END {
print "------------------------"
printf "全班平均分: %.2f\n", total_sum / NR
}

运行脚本:

bash
awk -f process.awk students.txt
# 或者给脚本文件添加执行权限后直接运行
chmod +x process.awk
./process.awk students.txt


[root@hadoop ~]# awk -f process.awk students.txt
=== 学生成绩报告 ===
Name       Average  Grade
------------------------
Alice      91.67    A
Bob        81.00    B
Carol      89.33    B
David      70.00    C
------------------------
全班平均分: 83.00

http://www.dtcms.com/a/564947.html

相关文章:

  • iBM(i2)图表数据优化及重点人员分析(三)
  • 做两个一摸一样的网站有没有专门做家乡图片的网站
  • Ubuntu 22.04 离线升级 OpenSSH 到 9.8p1
  • Dify 插件开发与打包教程 (Mac)
  • FastMCP 入门:用 Python 快速搭建 MCP 服务器接入 LLM
  • 常见DGX A100服务器维修故障问题及解决方法
  • Linux系统编程——exec函数族
  • 简单搭建express服务器
  • 设置网站建设大连专业网站设计服务商
  • Ollama + Open WebUI
  • 张家界市建设工程造价管理站网站好看的ui界面
  • 【WEB应用安全】XSS攻击实验全流程实战!从漏洞检测到Cookie窃取(附Payload解析+避坑指南)
  • Linux系统启动流程深度解析:从BIOS到用户空间的全链路指南
  • AI编程工具TRAE解决日常问题之SQLite数据复制
  • 百度网盘下载速度被限制怎么办?百度网盘如何解除限速下载方法
  • 多协议网关架构
  • 深入级联不稳定性:从 Lipschitz 连续性视角探讨图像恢复与目标检测的协同作用
  • 如何实现html显示WebRTC视频监控流
  • 长沙网站设计服务商wordpress和vue
  • DeepSeek-OCR 深度解析
  • [手机AI开发sdk] Aid_code IDE | PC浏览器同步访问
  • 视觉语言模型(VLM)深度解析:如何用它来处理文档
  • 空载长线电容效应
  • Text Grab,一款OCR 截图文字识别工具
  • 网站建设与管理教学方案网站的技术解决方案
  • 从零开始学习iOS App开发:Xcode、Swift和发布到App Store完整教程
  • HTMLCollection 对象
  • CANN算子开发实战:Batch Normalization高性能实现指南
  • 【Delphi】再谈给EXE文件动态添加数据(附加大数据 2G)
  • 1、Python-内置函数、Pass空语句