Linux学习日记 —— shell 编程文本三剑客之 awk

awk 是什么?

awk 和 sed、grep 一样,是 Linux 当中处理文本文件非常好用的一个命令,它是Linux中的一个行处理器,它的处理过程是:格式化文本信息后,依次对行进行操作,并输出对应内容。

awk 的完整用法: awk -? ‘BEGIN{语法} /字段选择/ {print ; 语句} END{XXXX}’

awk 用法解析:

’-?'

-? 内容 用法
-F 指定分割符
-f 调用脚本
-v 引入shell变量,可以自己定义变量

BEGIN{语法}

  • **BEGIN:**初始化代码块,在对每一行进行处理之前,初始化代码;
  • **{语法}:**命令代码块,里面可以包含一条或者多条命令,多条命令之间用分号(;)进行分隔开,在BEGIN这里的打括号里接的代码内容多是:初始化全局变量设置分割符 等。

/字段选择/ {print ; 语句}

  • / xxxx /: 这里的字段选择内容可以选择你想匹配的代码块,也可以是字符串,还能使用正则表达式对目的字段进行选择;
  • {语句 ; 语句}: 这里也是可以接多条语句,用的最多的就是 print 语句,可以暑促想要匹配的文本内容。

END{XXXX}

  • END: 结尾代码块,在对每一行进行处理之后再执行的代码块;
  • {XXXX}: 这里主要接的是进行最终计算或输出最后结果的代码语句。

awk 用法简易展示

在这里对后面展示出现的 $0 的含义进行解释, $0 在 awk 中指的是当前选中的行的内容,后面的 $1、$2 … $n 等都是指的是第 n 列的内容。

awk '{print $1,$5}' 
# 截取第一列和第五列(awk默认把所有的空白当作分隔符)

awk '$1 ~ /RX/ {print $0}'
# 匹配第一列是RX的 并输出一整行

Linux学习日记 —— shell 编程文本三剑客之 awk_第1张图片
这里可以观察和一下该命令的效果,必须要第一列是 RX 才会输出对应行的内容。

awk '$x ` /xxx/ && $y ~ /xxxxx/  || $a ~ /xxxxxx/  && $b ~ /xxxxxxxa/ {print}'
# 这一段话的意思是 满足第x列和第y列的条件或者满足第a列和第b列的条件就能输出
# 同样 可以在这里看出,在 linux 中,and 比 or 的优先级更高

Linux学习日记 —— shell 编程文本三剑客之 awk_第2张图片
看看效果,oh,这个效果真好用!

awk '$0 ` /RX.*XXXX|TX.*XXXXXX/{print xxx}'
# 如果行满足RX 或者 TX这两个中的一个条件  就输出什么什么

按照惯例,直接上手看看:
Linux学习日记 —— shell 编程文本三剑客之 awk_第3张图片
这里是选中里面含有 ame 或者 AMEAME 这两个文本内容行,然后输出选中行文本的第一列的元素。这个还蛮好玩的。

 - 来一段有点难度的 awk 代码玩一玩!
cat /etc/passwd |awk -F: 'BEGIN{i=0;m=0;n=0}{if($3==0)print $1,"管理员",i++;else if($3>=1&&$3<=999)print $1,"程序用户",m++;else print $1,"普通用户",n++}END{print "管理员有"i"个,程序用户有"m"个,普通用户有"n"个。"}'
# 让我们一起来统计一下当前 Linux 系统中有多少管理员用户、程序用户和普通用户

要彻底理解这串代码之前,我们先 cat /etc/passwd:
Linux学习日记 —— shell 编程文本三剑客之 awk_第4张图片
我们可以看到每一行对应的是一个用户,每一行的第一个数字(x:num 数字指的就是 x 对应的第一个num)就是该用户的等级:

num 用户
0 管理员用户
大于0,小于1000 程序用户
其他 普通用户

这里我们粗略的看一下,似乎没有什么普通用户,我们使用 useradd 来新建几个。
Linux学习日记 —— shell 编程文本三剑客之 awk_第5张图片
ok 现在我们新建了几个 wangchunyu 的用户,可以看到他们都属于普通用户,好的现在来解析这串 awk 的长代码:

 - 这里我将 awk 按照博主前面的分段介绍的方式进行分段解释,这里不要直接复制代码使用
awk -F: 
 - 这里对应的是 awk 的 -? 这一段,-F 的意思是指定分割符,所以这一块的意义是指将这个文件中的 : 视为分割符
BEGIN{
     i=0;m=0;n=0}
 - 这里 BEGIN 在代码的一开始新建了3个元素 i、m、n 用来计数
{
     if($3==0)print $1,"管理员",i++;else if($3>=1&&$3<=999)print $1,"程序用户",m++;else print $1,"普通用户",n++}
 - 这里是 //{
     } 代码段,由于不需要进行字段匹配所以 // 内容为空 可以不写
 - 然后{
     }中间是一个 if 流程控制语句,判断第三列的数值所属区间(这里通过看上面 cat /etc/passwd 的内容可以发现,以:为分割符的情况下,代表用户等级的数字处在第三列)
 - 通过对第三单列的用户等级数值的判断,分别使用 i、m、n 来分别计数,统计不同用户的数量
END{
     print "管理员有"i"个,程序用户有"m"个,普通用户有"n"个。"}'
 - 最后用 END 块在 awk 语句执行完毕只会做最后统计数值的输出

代码分析过程到此结束,我们一起来看看运行的结果如何:
Linux学习日记 —— shell 编程文本三剑客之 awk_第6张图片
嗯~ 就和吃了蜂王浆一样舒服!

awk 支持的函数

这后面的内容比较多,就不再一个个的使用展示了
下面提到的函数可以放在 {} (命令代码块) 中使用

字符函数 String Functions

  • length()
  • match(s,r,[,a])
  • patsplit
  • split(s,a[,r[,seps]])
  • sub()
  • index()

数学函数

  • atan2(y,x): 反正切函数
  • cos(x): 余弦函数
  • sin(x): 正弦函数
  • exp(x):以自然对数e为底指数函数
  • log(x): 计算以e为底的对数值
  • sqrt(x): 开根号
  • sqrt(x*x)可以达到取绝对值的目的
  • int(x): 将数值转换成整数
  • rand(): 返回0-1的一个随机数值,不包含1
  • srand([expr]): 设置随机种子,一般与rand函数一致

进程和进程之间通信的方式

  1. 共享内存
  2. 信号量
  3. 信号
  4. 管道
  5. 队列

来举几个 awk 中通信的例子

sg="wangchunyu"
echo $sg
# 输出 wangchunyu
echo | awk '{print $sg}'
# 输出为空
echo | awk -v bsg=$sg '{print bsg}'
# 输出 wangchunyu

在 awk 中想访问外部定义的变量 需要通过 -v 将外部变量的值赋值给自己定义一个 shell 变量,才能达到正常输出的效果。

awk 的一些基本用法的学习到这里就结束了,如果想看更多请关注这个走在学习路上的博主,周更学习日志。
Linux文本三剑客 - sed.
Linux文本三剑客 - grep (正在写作中)


如果想学习更多,欢迎来访 三创.

你可能感兴趣的:(shell编程,Linux,文本三剑客,linux,shell,awk)