文本三剑客之awk命令

概念
  • awk是Linux以及UNIX环境中现有的功能最强大的数据处理工具,awk其名称得自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母

  • awk是一种处理文本数据的编程语言,适合文本处理和报表生成,awk的设计使得它非常适合于处理由行和列组成的文本数据。

  • awk 还是一种编程语言环境,它提供了正则表达式的匹配,流程控制,运算符,表达式,变量以及函数等一系列的程序设计语言所具备的特性,它从C语言中获取了一些优秀的思想

工作流程

如图:

image-20230207093838609

流程:
  • 第一步:自动从指定的数据文件中读取行文本。

  • 第二步:自动更新awk的内置系统变量的值,例如列数变量NF、行数变量NR、行变量$0以及各个列变量$1、$2等等

  • 第三步:依次执行程序中所有的匹配模式及其操作

  • 第四步:当执行完程序中所有的匹配模式及其操作之后,如果数据文件中仍然还有为读取的数据行,则返回到第(1)步,重复执行(1)~(4)的操作。

awk命令的基本语法

  • 任何awk语句都由模式(pattern)和动作(action)组成

    • 模式:由一组用于测试输入行是否需要执行动作的==规则==

    • 动作:包含语句,函数和表达式的执行过程

    • 简言之,模式决定动作何时触发和触发事件,动作执行对输入行的处理

格式:
awk 'BEGIN{ commands } pattern{ commands } END{ commands }' [INPUTFILE…]
# 以上三部分可选
BEGIN模式与END模式
  • BEGIN模式是一种特殊的内置模式,其执行的时机为awk程序刚开始执行,但是又尚未读取任何数据之前。因此,该模式所对应的操作仅仅被执行一次,当awk读取数据之后,BEGIN模式便不再成立。所以,用户可以将与数据文件无关,而且在整个程序的生命周期中,只需执行1次的代码放在BEGIN模式对应的操作中,一般用于打印报告的标题和更改内在变量的值

  • END模式是awk的另外一种特殊模式,该模式执行的时机与BEGIN模式恰好相反,它是在awk命令处理完所有的数据,即将退出程序时成立,在此之前,END模式并不成立。无论数据文件中包含多少行数据,在整个程序的生命周期中,该模式所对应的操作只被执行1次。因此,一般情况下,用户可以将许多善后工作放在END模式对应的操作中EN,一般用于打印总结性的描述或数值总和

[root@server ~]# awk  'BEGIN {print  "BEGIN..."}  {print  $0}  END {print "The End"}'  /etc/fstab
​
[root@server ~]# awk  'BEGIN {print "line one \n line two \n line three"}'
​
[root@server ~]# awk  'BEGIN {print "this is  test"}'


awk的输出
格式:

awk 'BEGIN{ commands } {print item1,item2,……} END{ commands }' [INPUTFILE…]
  • 各项目之间使用逗号隔开,而输出时则以空格字符分隔

  • 输出的item可以为字符串或数值、当前记录的字段(如$1)、变量或awk的表达式;数值会先转换为字符串,然后再输出

awk程序执行方式

通过命令行执行awk程序
[root@server ~]# vim   input
# 输入多个回车符
​
[root@server ~]# awk  '/^$/{print  "This is  a  blank  line"}'   input 
awk命令调用脚本执行
  • 在awk程序语句比较多的情况下,用户可以将所有的语句写在一个脚本文件中,然后通过awk命令来解释并执行其中的语句。awk调用脚本的语法如下

awk -f program-file  file 
  • -f选项表示从脚本文件中读取awk程序语句,program-file表示awk脚本文件名称,file表示要处理的数据文件

[root@server ~]# vim  scr.awk   # 新建awk脚本,输入以下内容
/^$/{print  "This is  a  blank  line"}
​
[root@server ~]# awk  -f  scr.awk input 
直接使用awk脚本文件调用
  • 在上面介绍的两种方式中,用户都需要输入awk命令才能执行程序。除此之外,用户还可以通过类似于Shell脚本的方式来执行awk程序。在这种方式中,需要在awk程序中指定命令解释器,并且赋予脚本文件的可执行权限。其中指定命令解释器的语法如下

#!/bin/awk -f
以上语句必须位于脚本文件的第一行

通过以下命令执行awk程序:

./awk-script.awk   file
例:

[root@server ~]# vim   scr.awk
#!/bin/awk  -f    # 注意需要增加,表示使用什么解释器来执行
/^$/{print  "This is a blank  line."}
​
[root@server ~]# chmod  o+x  scr.awk 
[root@server ~]# ./scr.awk   input 

记录和域

概念
  • awk认为输入文件是结构化的,awk将每个输入文件行定义为记录,行中的每个字符串定义为,域之间用空格,Tab键或其他符号进行分隔,分隔域的符号就叫做分隔符,默认为空格或tab

  • awk定义域操作符$来指定执行动作的域,域操作符$后面跟数字或变量来标识域的位置,每条记录的域从1开始编号,如$1表示第一个域 $0表示所有域

# 准备示例文件
[root@server ~]# vim  awk1.txt
# 输入以下内容
Li xiaoming xian 13311111111
zhang cuihua baoji 13322222222
wang xiaoer xianyang 13333333333
[root@server ~]# vim  awk1.txt
[root@server ~]# awk  '{print  $0}'  awk1.txt    # 所有域
Li xiaoming xian 13311111111
zhang cuihua baoji 13322222222
wang xiaoer xianyang 13333333333
[root@server ~]# awk  '{print  $1}'  awk1.txt   # 第一个域,即第一列
Li
zhang
wang
[root@server ~]# awk  '{print  $2}'  awk1.txt 
xiaoming
cuihua
xiaoer
[root@server ~]# awk  '{print  $3}'  awk1.txt 
xian
baoji
xianyang
[root@server ~]# awk  '{print  $4}'  awk1.txt   # 第4例
13311111111
13322222222
13333333333
# 操作符$之后可以跟变量或表达式
[root@server ~]# awk  'BEGIN {one=1;two=2} {print $(one+two)}'  awk1.txt 
xian
baoji
xianyang
[root@server ~]# awk  '/^[^#]/{print  $3}'  /etc/fstab 
xfs
xfs
swap
# ^[^#]表示不以#开头的行
#检索包含swap的第一列信息
[root@server ~]# awk  '/swap/{print $1}'  /etc/fstab 
使用-F 参数指定域的间隔符
# 查询文件中的所有账户名
[root@server ~]# awk  -F  ":"  '{print  $1}'  /etc/passwd # 指定冒号为分隔符
​
#查询文件中的UID与GID
[root@server ~]# awk  -F ":"  '{print  $3,$4}'  /etc/passwd
通过系统变量FS改变分隔符
awk默认的分隔符存储在FS变量中,默认为空格或tab

[root@server ~]# awk  'BEGIN {print  $FS}'
设置FS变量改变域分隔符

[root@server ~]# awk  'BEGIN {FS=":"} {print $2}'  /etc/passwd
NR、NF、FILENAME量
  • 概念:

    • NR变量表示记录数,即被处理过的行数

    • NF变量表示记录的域数量

    • FILENAME:处理的文件名

  • 示例

[root@server ~]# awk  '{print NF,NR,$0} END {print FILENAME}'  awk1.txt 
4 1 Li xiaoming xian 13311111111
4 2 zhang cuihua baoji 13322222222
4 3 wang xiaoer xianyang 13333333333
awk1.txt
[root@server ~]# awk  '{print "第",NR,"行","有",NF,"域" > "/root/t1.txt"}'   awk1.txt
[root@server ~]# cat t1.txt 
第 1 行 有 4 域
第 2 行 有 4 域
第 3 行 有 4 域

awk的变量

概念
  • 与其他的程序设计语言一样,awk本身支持变量的相关操作,包括变量的定义和引用,以及参与相关的运算等。此外,还包含了许多内置的系统变量

  • 变量的作用是用来存储数据。变量由变量名和值两部分组成,其中变量名是用来实现变量值的引用的途径,而变量值则是内存空间中存储的用户数据

  • awk的变量名只能包括字母、数字和下划线,并且不能以数字开头。例如abc、az以及a123都是合法的变量名,而123abc则是非法的变量名。另外,awk的变量名是区分大小写的,因此,X和x分别表示不同的变量

  • awk中的变量类型分为两种,分别为字符串和数值。但是在定义awk变量时,毋需指定变量类型,awk会根据变量所处的环境自动判断。==如果没有指定值,数值类型的变量的缺省值为0,字符串类型的变量的缺省值为空串==

内置变量
变量作用
$0记录变量,表示所有列的内容
$n字段变量,表示第n个列的内容
NF当前行的列个数
NR显示每一行的行号
FS输入字段分隔符,默认值是空格或者制表符,可使用-F指定分隔符
OFS输出字段分隔符 ,OFS=”#”指定输出分割符为#
RS记录分隔符,默认值是换行符 \n
ENVIRON当前shell环境变量及其值的关联数组
示例

# 准备数据文件
[root@server ~]# vim  awk2.txt  # 输入以下内容
zhangsan 68 88 92 45 71
lisi     77 99 63 52 84
wangwu   61 80 93 77 81
[root@server ~]# vim  test.awk
​
{
        print
        print "$0:",$0
        print "$1:",$1
        print "$2:",$2
        print "NF:",NF
        print "NR:",NR
        print "FILENAME:",FILENAME
}       
​
# awk命令调用脚本
[root@server ~]# awk  -f  test.awk  awk2.txt
# OFS设置输出结果的间隔符为\t
[root@server ~]# awk  -F  ":"  'BEGIN {OFS="\t"} {print $1,$2}'  /etc/passwd
# 京东面试题:查看文件中所有空白行的行号
[root@server ~]# awk  '/^$/{print  NR}'  /root/anaconda-ks.cfg 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

桔梗.py

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值