shell脚本四剑客之awk详解

news/2024/12/2 21:44:59/

文章目录

    • awk的介绍
    • awk能够干什么
    • awk的格式
    • 工作原理:
    • 记录和域
      • 内建变量的用法
        • 1. FS
        • 2. OFS
        • 3.RS
        • 4. ORS
        • 5. NF
        • 6. NR
    • BEGIN 和END语句块
    • 常见案例
      • 1. 使用NR行号提取ip
      • 2. 打印UID小于10的账号名称和UID信息
      • 3. 数学运算
      • 4. AWK打印硬盘设备名称,默认以空格为分割:
      • 5. AWK以空格、冒号、\t(Tab缩进) 、分号为分割显示第4列内容:
      • 6. AWK以冒号分割,打印第一列,同时将内容追加到/tmp/awk.log下:
      • 7. 打印test.txt文件中的第3行至第5行(2种写法):NR表示打印行,$0表示文本所有域:
      • 8. 打印test.txt文件中的第3行至第5行的第一列与最后一列:
      • 9. 打印test.txt文件中,长度大于80的行号:
      • 10. AWK引用Shell变量,使用-v或者双引号+单引号即可:
    • 总结

awk的介绍

shell脚本中最难的不是shell的语法难,而是在shell编程这门语言中,又突然出来一门编程语言,这个编程语言叫: awk

awk以用来处理数据和生成报告(excel);
处理的数据可以是一个或多个文件;可以是直接来自标准输入,也可以通过管道获取标准输入;

awk可以在命令行上直接编辑命令进行操作,也可以编写成awk程序来进行更为复杂的运用。

awk能够干什么

学习具体使用前,先来看下 awk 能干些什么事情:

  1. 能够将给定的文本内容,按照我们期望的格式输出显示,打印成报表。
  2. 分析处理系统日志,快速地分析挖掘我们关心的数据,并生成统计信息;
  3. 方便地用来统计数据,比如网站的访问量,访问的 IP 量等;
  4. 通过各种工具的组合,快速地汇总分析系统的运行信息,让你对系统的运行了如指掌;
  5. 强大的脚本语言表达能力,支持循环、条件、数组等语法,助你分析更加复杂的数据;
    6
    awk 不是万能的,它比较擅长处理格式化的文本,比如 日志、csv 格式数据等;

awk的格式

简单结构:
awk [选项] ‘模式 {动作}’ 输入文件

awk [options] ‘pattern{attion}’ file

  • 模式即pattern,可以类似理解成sed的模式匹配,可以由表达式组成,也可以是两个正斜杠之间的正则表达式。比如NR==1,这就是模式,可以把它理解为一个条件。

  • 动作即action,是由在大括号里面的一条或多条语句组成,语句之间使用分号隔开。

详细结构

awk ‘BEGIN{ print “start” } pattern{ commands } END{ print “end” }’ filename

一个 awk 脚本通常由 BEGIN 语句 + 模式匹配 + END 语句三部分组成,这三部分都是可选项

工作原理:

简单版:
第一步执行 BEGIN 语句
第二步从文件或标准输入读取一行,然后再执行 pattern 语句,逐行扫描文件到文件全部被读取
第三步执行 END 语句

在这里插入图片描述

详细执行流程:

  • 首先执行关键字 BEGIN 标识的 {} 中的命令;
  • 完成 BEGIN 大括号中命令的后,开始执行 body 命令;
  • 逐行读取数据,默认读到 \n 分割的内容为一条 记录,其实就是行的概念;
  • 将记录按照指定的分隔符划分为 字段,其实就是列的概念;
  • 循环执行 body 块中的命令,每读取一行,执行一次 body,最终完成 body 执行;
  • 最后,执行 END 命令,通常会在 END 中输出最后的结果;

awk 是输入驱动的,有多少输入行,就会执行多少次 body 命令

我们在学习过程中,要时刻记着:

记录 (Record) 就是行
字段 (Field) 就是列
BEGIN 是预处理阶段
body 是 awk 真正工作的阶段
END 是最后处理阶段。

案例: 输出test.txt中的每一行

[root@itlaoxin41 ~]# awk '{print $0}' test.txt
cccc
old new old now 

在这个案例中: awk每次读取一行
具体的执行过程:

  • 读取文件第一行 (awk 默认按行读取文件)
  • 将所读取的行赋值给 awk 的变量 $0,于是 $0 中保存的就是本次所读取的行数据
  • 进入代码块 {print $0} 并执行其中代码 print $0,即输出 $0,也即输出当前所读取的行
  • 执行完本次代码之后,进入下一轮 awk 循环:继续读取下一行 (第二行)


全部读取完成后,退出awk

记录和域

域标记: awk执行时,其浏览标记为$1,2...2...2...n,这种方法称为域标记

$1 表示参照第一域, 多个域用,分割,比如$1,$3
$0 表示所有域

内置变量:

···

NR:表示当前的行数;
NF:表示当前的列数;
RS:行分隔符,默认是换行;
FS:列分隔符,默认是空格和制表符;
OFS:输出列分隔符,用于打印时分割字段,默认为空格
ORS:输出行分隔符,用于打印时分割记录,默认为换行符

案例:

以冒号为分隔符,打印第三个域

[root@itlaoxin41 ~]# awk -F ":" '{print $3}' /etc/passwd

假设我们想截取多列,比如:

截取用户名,用户ID,家目录和bash

[root@itlaoxin41 ~]# awk -F ":" '{print $1,$3,$6,$7}' /etc/passwd
root 0 /root /bin/bash

这里需要知道,awk默认以空格为分隔符

内建变量的用法

1. FS

指定列分隔符
···

[root@itlaoxin41 ~]# echo "111|222|333" |awk '{print $1}'
111|222|333
[root@itlaoxin41 ~]# echo "111|222|333" |awk 'BEGIN{FS="|"}{print $1}'
111
[root@itlaoxin41 ~]# 

2. OFS

输出列分隔符,用于打印时分割字段,默认为空格

[root@itlaoxin41 ~]# echo "111 222 333" |awk 'BEGIN{OFS="/"}{print $1,$2}'
111/222
[root@itlaoxin41 ~]# echo "111 222 333" |awk 'BEGIN{OFS="/"}{print $1,$2,$3}'
111/222/333
[root@itlaoxin41 ~]# 

3.RS

行分隔符,默认是换行符;

[root@itlaoxin41 ~]# echo "111 |222|333|444" |awk 'BEGIN{RS="|"}{print $0}'
111 
222
333
444

4. ORS

ORS指定输出行分隔符

[root@itlaoxin41 ~]# echo "111 |222|333|444" |awk 'BEGIN{RS="|"}{print $0}'>test.sh[root@itlaoxin41 ~]# cat test.sh
111 
222
333
444[root@itlaoxin41 ~]# awk 'BEGIN{ORS="|";}{print $0}' test.sh
111 |222|333|444||

5. NF

当前的列数

[root@itlaoxin41 ~]# cat test.sh 
111 
222
333
444[root@itlaoxin41 ~]# awk '{print NF}' test.sh
1
1
1
1
0

6. NR

当前行的行数

[root@itlaoxin41 ~]# cat test.sh 
111 
222
333
444[root@itlaoxin41 ~]# awk '{print NR}' test.sh
1
2
3
4
5

BEGIN 和END语句块

awk程序由三部分组成,分别为

初始化:处理输入前做的准备,放在BEGIN块中。
数据处理:处理输入数据。

收尾处理:处理输入完成后要进行的处理,放到END块中。

其中,在“数据处理”过程中,指令被写成一系列模式/动作过程,模式是用于测试输入行的规则,以此确定是否将应用于这些输入行。

awk 的所有代码 都是写在语句块中的

root@itlaoxin41 ~]# awk -F ":" '{print $1}' passwd |head -3
root
ceshi
no such person

语句块可分为 3 类: BEGIN语句块, END语句块,和main语句块

其中 BEGIN 语句块和 END 语句块都是的格式分别为 BEGIN{…} 和 END{…}

main 语句块是一种统称,它的 pattern 部分没有固定格式,也可以省略,main 代码块是在读取文件的每一行的时候都执行的代码块。

且:
BEGIN代码块:

  • 在读取文件之前执行,且执行一次
  • 在BEGIN代码块中,无法使用 $0 或者其他变量

main 代码块:

  • 读取文件时循环执行,(默认情况) 每读取一行,就执行一次 main 代码块
  • main 代码块可有多个

END代码块

  • 在读取文件完成之后执行,且执行一次
  • 有 END 代码块,必有要读取的数据 (可以是标准输入)
  • END 代码块中可以使用 $0 等一些特殊变量,只不过这些特殊变量保存的是最后一轮 awk 循环的数据

常见案例

1. 使用NR行号提取ip

[root@itlaoxin41 ~]# ifconfig |grep inet |awk 'NR==1{print $2}'
192.168.1.41

2. 打印UID小于10的账号名称和UID信息

[root@itlaoxin41 ~]# awk -F : '$3 < 10{print $1,$3}' /etc/passwd
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8

3. 数学运算

加法:awk ‘{a=1; b=2; print a+b}’
减法:awk ‘{a=1; b=2; print a-b}’
乘法:awk ‘{a=1; b=2; print a*b}’
除法:awk ‘{a=1; b=2; print a/b}’
取余:awk ‘{a=1; b=2; print a%b}

4. AWK打印硬盘设备名称,默认以空格为分割:

df -h|awk '{print $1}'     $1 第一列

5. AWK以空格、冒号、\t(Tab缩进) 、分号为分割显示第4列内容:

awk -F '[ :\t; ]' '{print $4}' test.txt

6. AWK以冒号分割,打印第一列,同时将内容追加到/tmp/awk.log下:

awk -F: '{print $1 >>"/tmp/awk.log"}' test.txt

7. 打印test.txt文件中的第3行至第5行(2种写法):NR表示打印行,$0表示文本所有域:

awk 'NR==3,NR==5 {print}' test.txt
awk 'NR==3,NR==5 {print $0}' test.txt

8. 打印test.txt文件中的第3行至第5行的第一列与最后一列:

awk 'NR==3,NR==5 {print $1,$NF}' test.txt

备注:默认情况下,awk操作的文本以空格或者缩进格(Tab)为列的分界序列

9. 打印test.txt文件中,长度大于80的行号:

awk 'length($0)>80 {print NR}' test.txt

10. AWK引用Shell变量,使用-v或者双引号+单引号即可:

`awk -v STR=hello '{print STR,$NF}' test.txt`  #test.txt每行前加入hello打印
STR="hello";echo|awk '{print "'${STR}'";}'      #需要订正!

总结

AWK没有一万字写不完,这刚刚开始就干到了4500字, 足够你学习用了。


http://www.ppmy.cn/news/6706.html

相关文章

买不到的数目(蓝桥杯C/C++A组真题详解)

题目详细&#xff1a; 题目思路&#xff1a; 对于这个题有一个定理 如果 a,b 均是正整数且互质&#xff0c;那么由 axby&#xff0c;x≥0&#xff0c;y≥0 不能凑出的最大数是 &#xff1a; a*b-a-b 具体的证明过程这里就不赘述 感兴趣的同学可以自行查找 这里就提供一种思…

Python常见问题整理

Python常见问题整理   日常使用python时&#xff0c;经常遇到的各种解决不了、头疼的问题&#xff0c;都可以记录到这里&#xff0c;大家群策群力&#xff0c;积极补充~  序号问题标题问题现象原因解决方法参考文章添加人报错截图0ModuleNotFoundError代码运行报错ModuleNot…

IMX6ULL学习笔记(15)——GPIO输出接口使用【官方SDK方式】

一、GPIO简介 i.MX6ULL 芯片的 GPIO 被分成 5 组,并且每组 GPIO 的数量不尽相同&#xff0c;例如 GPIO1 拥有 32 个引脚&#xff0c; GPIO2 拥有 22 个引脚&#xff0c; 其他 GPIO 分组的数量以及每个 GPIO 的功能请参考 《i.MX 6UltraLite Applications Processor Reference M…

人员工装未穿戴识别检测 opencv

人员工装未穿戴识别检测基于OpenCvyolo计算机视觉深度学习技术对现场画面中人员行为着装穿戴实时监测识别&#xff0c;发现不按要求着装违规行为立即抓拍存档同步后台。OpenCV-Python使用Numpy&#xff0c;这是一个高度优化的数据库操作库&#xff0c;具有MATLAB风格的语法。所…

【C语言进阶】想用好C++?那就一定要掌握动态内存管理

目录 &#x1f929;前言&#x1f929;&#xff1a; 一、动态内存概述⚔️&#xff1a; 1.什么是动态内存&#xff1a; 2.动态内存分配的意义&#xff1a; 二、常用的动态内存函数&#x1f3f9;&#xff1a; 1. malloc 和 free函数&#xff1a; ①. malloc 函数&#xff1a; …

Windows和Mac系统实现本地部署WebPageTest工具

在项目开发或者测试的过程中&#xff0c;由于没有上线&#xff0c;我们在公网上无法访问我们的网站&#xff0c;但同时我们又需要查看浏览器性能&#xff0c;这样我们就需要在本地部署WebPageTest工具以协助进行性能测试 具体实现步骤&#xff1a; Windows系统&#xff1a; …

关于 Camera 开始 Tuning 时的一些注意事项

1、问题背景&#xff1a; 最近有调试一个体感游戏机上带 Camera 的项目&#xff0c;原定搭配 ov13855 这颗 sensor, 但由于各种各样的问题&#xff0c;导致做了很多无用功&#xff0c;且各种延期。 本文主要总结下此次项目遇到的问题&#xff0c;及产品开始 tuning 时的一些注意…

git覆盖本地代码

git stash --include-untracked git reset --hard git clean -fd git pull