Shell|awk学习及实例

1.awk功能介绍 awk是基于指定规则从文本文件和字符串中抽取和浏览信息。比如用户登录日志中筛选特定用户日志记录做统计或者查看。
2.awk调用方式 (1)命令行方式:awk[-F 域分隔符]'awk程序段'输入文件
例子:awk-F :'{printf $0} '/etc/passwd
(2)awk命令放入脚本文件(脚本第一行:#!/bin/awk -f),然后通过awk调用脚本文件。
调用形式:awk-fawk脚本文件输入文件
(3)awk命令放入脚本文件(脚本第一行:#!/bin/awk -f),设置该脚本文件为可执行文件。
调用形式:./awk脚本文件输入文件
3.awk脚本 (1)域和记录
域:awk输入内容按照分隔符划分的各部分,比如$1表示第1域、$7表示第7域、$0表示所有记录(包括域内容和分隔符)。
记录:awk输入内容的一行内容。
Shell|awk学习及实例
文章图片

(2)模式和动作
awk脚本由模式和动作组成,模式部分是决定动作语句何时触发,动作部分是对数据进行的操作。
Shell|awk学习及实例
文章图片

例子中 BEGIN{..}和END{...}属于模式部分。BEGIN部分是awk读取输入文件记录之前执行,一般用来初始化计数变量和打印表头;END部分是awk读取输入文件内容之后执行,一般用作输出统计数值和输出格式化内容的结束标志;另外模式可以是任何条件语句或复合语句或正则表达式。
中间{...}里是动作部分,用来打印符合模式的内容。print是内容输出函数。
(3)awk输出内容保存方式:重定向到文件和tee命令
比如awk处理的passwd.bak文件的内容保存到result.txt文件中
重定向到文件方式:awk '{print $0}'passwd.bak > result.txt
tee命令方式: awk '{print $0}' passwd.bak | tee result.txt
注意:<1>重定向到文件方式输出数据不再打印到屏幕,tee命令则会打印到屏幕
<2>重定向方式注意“>”和“>>”的区别,“>”会覆盖文件里面的原内容,“>>”则是在文件里面追加内容。
(4)awk输入方式:
<1> awk-scriptinput-file
<2>awk-script-file < input-file
<3>input-file | awk-script-file
<4>shell命令结果向awk传入字符串,比如:
Shell|awk学习及实例
文章图片

<5> awk命令后面没有输入文件时,可以通过键盘输入内容,比如:
awk '{print $1,$3}'
需要输入内容后按结束
(5)awk打印所有记录、打印特定域、打印开头、打印结尾
打印所有记录:awk '{print $0}'passwd.bak
打印特定域(特定列数据):awk '{print $1,$7}'passwd.bak
打印开头:awk 'BEGIN{print"user login-mode"}{print $1,$7}'passwd.bak
打印结尾:awk '{print $1,$7}END{print "field-1 filed-7"}'passwd.bak
4.awk编写注意事项 (1)整个awk命令使用单引号括起来。
(2)命令内所有引号和花括号成对出现。
(3)花括号括起动作语句,圆括号括起条件语句。
5.awk正则表达式及操作实例 Shell|awk学习及实例
文章图片
6. 元字符

awk中的元字符
元字符 用法及举例
\ 1. 将下一个字符标记为一个特殊字符,比如”n“是普通字符,"\n"匹配换行符。除此之外还有”\b‘表示退格符、“\r”回车键、“\t”表示tab键
2.将下一个字符标记为一个原义字符,比如”(“是有特殊用途的,内容中想用到的话需要用”\(“来表示。
3.将下一个字符标记为向后引用,比如输入命令一行没写完,可以在上一行加上”\“结尾,表示下一行命令继续。
4.将下一个字符标记为一个八进制转义符,比如”\0123“
awk 'BEGIN{b='\0123'; printf("%c\n",b)}' /dev/null
结果为:S
^ 匹配内容的开始位置,以root开头的可以表示为^root
$ 匹配内容的结束位置,以root结尾的可以表示为root$
. 匹配除换行符(\n、\r)之外的任何单个字符,比如
awk -F : '$1 ~ /^r..t$/{print $1}' passwd.bak
匹配"r"开头并且”t“结尾、中间任意2个字符的字符串
[] 字符范围,[xyz]
| 或者,x | y
() 括起条件语句,比如if()
* 匹配前面的子表达式零次或多次,比如”xy*“,可以是”x“或者”xyyy“
+ 匹配前面的子表达式一次或多次,比如”xy+“,可以是”xy“或者”xyyy“,不能是”x“
? 匹配前面的子表达式零次或一次,比如”xy?“,可以是”x“或者”xy“
6. 条件操作符
awk中的条件操作符
操作符 用途和举例
< 小于,比如awk -F : '{if($4 < 7) print $4}' passwd.bak
<= 小于等于,awk -F : '{if($4<=0) print $4}' passwd.bak
== 等于,awk -F : '{if($4==0) print $4}' passwd.bak
!= 不等于,awk -F : '{if($4!=0) print $4}' passwd.bak
>= 大于等于,awk -F : '{if($4>=0) print $4}' passwd.bak
~ 匹配正则表达式,比如awk '$0 ~ /root/{print $0}' passwd.bak
打印内容中包含”root“的记录
!~ 不匹配正则表达式,比如awk '$0 !~ /root/{print $0}' passwd.bak
打印内容中不包含”root“的记录
7.内置变量
awk常用内置变量
ARGC 命令行参数个数
ARGV 命令行参数排列
ENVIRON 支持队列中系统环境变量的使用
FILENAME awk浏览的文件名(输入文件的文件名)
FNR 浏览文件的记录数
FS(F) 设置输入域的分隔符
NF 浏览记录的域个数
NR 已读记录个数
OFS 输出域分隔符
ORS 输出记录分隔符
RS 控制记录分隔符

(1)打印文件内容并带记录号
Shell|awk学习及实例
文章图片

(2)提取绝对路径的文件名
Shell|awk学习及实例
文章图片

8.逻辑操作符
逻辑操作符
操作符 含义
&&(AND) 语句两边必须都为真时整体为真
|| (OR) 语句两边有1个为真时整体为真,全为假时整体为假
!

比如:Shell|awk学习及实例
文章图片


9.内置字符串函数
awk内置字符串函数
gsub(r,s) 整个$0中s替代r
gsub(r,s,t) 整个t中s替代r
index(s,t) 返回s中字符串t的第一个位置
length(s) 返回s的长度
match(s,r) 测试s是否包含匹配r的字符串
split(s,a,fs) 用fs将s分成序列a
sprint(fmt,exp) 返回fmt格式化后的exp
sub(r,s) 用$0中最左边最长的字符串代替s
substr(s,p) 返回字符串s中从p开始的后缀部分
substr(s,p,n) 返回字符串s中从p开始长度为n的后缀部分
10.输出函数printf和print Shell|awk学习及实例
文章图片

(1)从上图可以看出,print输出默认有个换行符,printf输出没有换行符。
(2)printf可以进行格式控制,形式为printf([格式控制符],参数),比如:
Shell|awk学习及实例
文章图片


11.数组 (1)构建数组:split(s,a,fs) 用fs将s分割为a序列,返回值为a序列的元素个数(a序列中空值也算个数)
例子:Shell|awk学习及实例
文章图片

数组使用前也可以不用定义,不用指定元素个数。
(2)访问数组:for (element in array) {print array[element]}
例子:
Shell|awk学习及实例
文章图片

awk中BEGIN部分按照“-”划分出数组color;END部分使用for循环访问数组,for循环中循环变量c取值为数组的下标值,awk正常执行需要/dev/null为输入文件结束awk,否则需要"ctrl+D"停止才能有结果。
(3)数组应用:文本内容统计
例子:统计/etc/passwd中“/sbin/nologin”、“/bin/bash”的用户个数分别有多少。
awk命令放入脚本文件,然后使用awk -fawk_script_fileintput_file执行,awk脚本文件如下:
Shell|awk学习及实例
文章图片

执行结果为:
Shell|awk学习及实例
文章图片

程序分析:awk的BEGIN部分设置输入分隔符为“:”,建立login数组的下标,数组并没有赋值;awk的循环部分指定mode变量读取数组的下标值,当读取文件的第7域值匹配到的下标元素值时将运行的总数保存进数组;END部分使用for循环读取数组中的下标元素值和该下标元素值对应的数组值。
awk循环部分执行的详细分析如图:
Shell|awk学习及实例
文章图片

12. awk应用 (1)统计某目录下所有文件的文件大小总和。
Shell|awk学习及实例
文章图片



【Shell|awk学习及实例】

    推荐阅读