shell脚本之awk工具详解

目录

  • 一、awk简介
  • 二、awk常见用法
    • 2.1、awk的内建变量
    • 2.2、按行输出文本
    • 2.3、按字段输出文本
    • 2.4、通过管道、双引号调用 Shell 命令
  • 三、getline命令

一、awk简介

  • 在 Linux/UNIX 系统中,awk 是一个功能强大的编辑工具,逐行读取输入文本,并根据指定的匹配模式进行查找,对符合条件的内容进行格式化输出或者过滤处理
  • 可以在无交互的情况下实现相当复杂的文本操作,被广泛应用于 Shell 脚本,完成各种自动化配置任务

二、awk常见用法

通常情况下 awk 所使用的命令格式为

[root@localhost ~]# awk 选项 '模式或条件 {编辑指令}' 文件 1 文件 2 „	'过滤并输出文件符条件的内容'
[root@localhost ~]# awk -f 脚本文件 文件 1 文件 2 „	'从脚本中调用编辑指令,过滤并输出内容'

其中,单引号加上大括号“{}”用于设置对数据进行的处理动作

awk 可以直接处理目标文件,也可以通过“-f”读取脚本对目标文件进行处理

  • sed 命令常用于一整行的处理,而 awk 比较倾向于将一行分成多个“字段”然后再进行处理,且默认情况下字段的分隔符为空格或者 tab 键,awk 执行结果可以通过 print 的功能将字段数据打印显示

  • 在使用 awk 命令的过程中,可以使用逻辑操作符“ && ”,表示“与”, “ || ”表示“或”,“!”表示“非”;还可以进行简单的数学运算,如+、-、*、/、%、^分别 表示加、减、乘、除、取余和乘方

[root@localhost ~]# awk -F ':' '{print $1,$3,$4}' /etc/passwd  '查看/etc/passwd的用户名($1),用户ID($3),组ID等列($4)'
$1,$3,$4之间用逗号隔开,输出的内容会有空格间隔
若$1 $3 $4之间不用逗号隔开,则输出的内容不会有空格间隔,会连在一起

2.1、awk的内建变量

变量 解释
FS 指定每行文本的字段分隔符,默认为空格或制表位(tab)
NF 当前处理的行的字段个数
NR 当前处理的行的行号(序数)
$0 当前处理的行的整行内容
$n 当前处理行的第n个字段(第n列)
FILENAME 被处理的文件名
RS 数据记录分隔,默认为\n,即每行为一条记录(\n表示回车)

2.2、按行输出文本

[root@localhost ~]# awk '{print}' test.txt 		'输出所有内容,等同于cat test.txt'
...省略内容
[root@localhost ~]# awk '{print $0}' test.txt 		'输出所有内容,等同于cat test.txt'
...省略内容
[root@localhost ~]# awk 'NR==1,NR==3{print}' test.txt 		'输出第1~3行内容'
...省略内容
[root@localhost ~]# awk '(NR>=1)&&(NR<=3){print}' test.txt 		'输出第1~3行内容'
...省略内容
[root@localhost ~]# awk 'NR==1||NR==3{print}' test.txt 		'输出1行,第3行内容'
...省略内容
[root@localhost ~]# awk '(NR%2)==1{print}' test.txt 		'输出所有奇数行内容'
...省略内容
[root@localhost ~]# awk '(NR%2)==0{print}' test.txt 		'输出所有偶数行内容'
...省略内容
[root@localhost ~]# awk '/^root/{print}' /etc/passwd 		'输出以root开头的行'
...省略内容
[root@localhost ~]# awk '/nologin$/{print}' /etc/passwd		'输出以 nologin 结尾的行'
...省略内容
[root@localhost ~]# awk 'BEGIN {x=0} ; /\/bin\/bash$/{x++};END {print x}' /etc/passwd  '统计以/bin/bash 结尾的行数,等同于 grep -c "/bin/bash$" /etc/passwd '
...省略内容
[root@localhost ~]# awk 'BEGIN{RS=""};END{print NR}' /etc/squid/squid.conf  	'统计以空行分隔的文本段落数'
...省略内容

2.3、按字段输出文本

[root@localhost ~]# awk '{print $3}' test.txt	'输出每行中(以空格或制表位分隔)的第 3 个字段'
...省略内容
[root@localhost ~]# awk '{print $1,$3}' test.txt	'输出每行中的第 1、3 个字段'
...省略内容
[root@localhost ~]# awk -F: '$2=="!!"{print}' /etc/shadow 	'输出密码为空的用户的shadow 记录'
...省略内容
[root@localhost ~]# awk 'BEGIN {FS=":"}; $2=="!!"{print}' /etc/shadow		'输出密码为空的用户的shadow 记录'
...省略内容
[root@localhost ~]# awk -F: '$7~"/bash"{print $1}' /etc/passwd		'输出以冒号分隔且第 7 个字段中包含/bash 的行的第 1 个字段'
...省略内容
[root@localhost ~]# awk '($1~"nfs")&&(NF==8){print $1,$2}' /etc/services	'输出包含 8 个字段且第 1 个字段中包含 nfs 的行的第 1、2 个字段'
...省略内容
[root@localhost ~]# awk -F: '($7!="/bin/bash")&&($7!="/sbin/nologin"){print}' /etc/passwd	'输出第 7 个字段既不为/bin/bash 也不为/sbin/nologin 的所有行'
...省略内容
[root@localhost ~]# awk -F “:” ‘{$NF = ""; print $0}’ /etc/shadow 删除最后一列输出

2.4、通过管道、双引号调用 Shell 命令

  • 操作命令放在{}中

  • 管道符号前面的命令输出的内容交给管道符号后面的命令处理

  • 结合正则表达式,正则表达式同样要被/包围

  • 调用的shell命令需要用""引起来

  • {}中多个命令之间也能过;分隔

[ root@localhost ~]# awk -F : '/bash$/{print | "wc -l"}' /etc/ passwd
7    
#调用wc -I命令统计使用bash的用户个数,效果等同于grep -C

[ root@localhost ~]# grep -c '/bash$' /etc/passwd
[root@localhost ~]# awk 1 BEGIN {while ("w" lgetline)n++;{print n-2}}'
2
#调用w命令,并用来统计在线用户数

[ root@localhost ~]# awk 'BEGIN{ "hostname" | getline;print}'
localhost. localdomain
#调用hostname命令,并输出当前主机名

三、getline命令

1.当getline左右没有重定向符|或<时,getline读去当前文件的第一行并将数据保存到变量中,如果没有变量,则数据保存到$0中;由于awk在处理getline之前已经读入了一行,所以getline得到的返回结果是隔行的。
2.当getline左右有重定向符|或<时,getline作用于定向输入文件,由于该文件是刚打开,awk并没有读入一行数据,而getline读入了一行数据,那么getline返回的是该文件的第一行,而不是隔行。

你可能感兴趣的:(shell脚本,shell,linux,awk,经验分享)