linux awk命令

awk是一个编程工具,他有完整的语法和命令。在bash中,awk更多的用于处理列内容(我是这么认为的,仅供参考)

awk程序的执行逻辑

      首先将文本内容读入到内存中,根据字段分隔符,在读取文本内容的过程中把读入的内容分段,第一个字段对应$1,第二个字段对应$2,依次类推,$0代表所有的字段。

注意:

      1、在awk程序中,变量的使用不需要带$符号,因为$符号表示字段。

      2、整个执行语句必须被'{}'包裹。

      3、awk程序,在处理文本的时候是一次处理一行内容。

 

先简单演示一下

linux awk命令

linux awk命令

这个例子中,awk程序将文本内容中的第二列和第四列进行了输出。

linux awk命令

这个例子主要是证明,awk每次处理一行内容。在例子中,awk处理了两行内容,所以hello输出的两次。字段之间用逗号隔开。

linux awk命令

这个例子中,hello与$2之间没有逗号,所以输出的内容中hello与$2所代表的的内容连在一起。

linux awk命令

这个例子中print后面没有跟任何参数,所以这个例子证明,print默认是输出所有内容

 

选项:

-F 指明输入时用到的字段分隔符

linux awk命令

这个例子中-F 指定了分隔符是:

 

变量

如果要使用变量就要使用-v这个选项

内建变量FS  这个等价于-F 读入文件时的分隔符 默认使用空白字符作为分隔符

linux awk命令

 

内建变量 OFS awk在输出时默认使用空白字符作为分隔符,也可以通过OFS进行指定

 

 

原本空白的地方被@替换了

 

内建变量RS,awk的在读入内容是的换行符,遇到这个符号就换行。默认使用\n作为换行符

linux awk命令

原本一行的内容被拆分成了若干行

 

内建变量ORS,awk在输出内容时默认使用\n作为换行符,也可以进行改变

linux awk命令

linux awk命令

这个例子中,需要注意的是每一个变量之前必须有一个-v的选项,不然系统会报错。

原本需要换行的输出,由于换行符改为#号,所以#号代替了换行。

 

内建变量NF 表示每一行字段的数量

linux awk命令

awk默认以空白符作为分隔符,/etc/passwd的每行内容基本上没有空白字符,所以一行就是一个分段。

linux awk命令

在读入文本内容时,以冒号作为分隔符,每一行被分为7段,那么NF就等于7

 

内建变量NR 打印读入内容的行编号

linux awk命令

如果有多个文件,那么awk默认会把所有内容看做一个文件

 

内建变量FNR 可以让awk分别对每个文件进行处理

linux awk命令

linux awk命令

 

内建变量FILENAME 每处理一行就输出内容所在文件的文件名

linux awk命令

内建变量ARGC 命令行参数的个数 输入的执行命令

linux awk命令

2表示执行的命令中有两个参数,更准确的说法是执行命令的字符串的个数是2:1、awk  2、/etc/issue

 

内建变量ARGV 这是个数组名,数组用来保存命令行中的参数

linux awk命令

 

自定义变量

awk本身就是一个编程工具,所以它支持自定义变量,

linux awk命令

这种变量赋值算一种提前赋值的方式,因为赋值的动作在执行命令之前。

linux awk命令

这种变量赋值算另一种赋值方式,赋值的动作在执行命令过程中

 

printf

这个命令的主要功能就是对输出内容进行制表操作,让输出的内容看起来更加美观

printf FORMAT,item1,item2

注意:1、printf没有默认格式,FORMAT必须给出。 2、printf不会自动换行,需要输出换行符 3、FORMAT需要为后面每一个需要输出的字段指定格式化符号(是以整数输出,还是字符串输出)

格式符:

           %c 显示为字符的ASCII码

           %d,%i 显示为十进制整数

           %f 显示为浮点数

           %g %G 以科学计数法或浮点形式显示数值

           %s 显示字符串

           %u显示为无符号整数

           %% 显示%自身

linux awk命令

printf 需要输出的内容需要用双引号引起来。

$1的内容需要用%s(字符串格式显示)

现在换一个显示格式

linux awk命令

相同的内容,显示格式不一样,输出就可能不一样

为了让输出内容更有可读性,我再改改

linux awk命令

linux awk命令

$1以%s的格式输出,$3以%d的格式输出,这是语法。

 

修饰符

#[.#] 第一个#号控制显示的宽度,第二个#号表示小数点后的精度

linux awk命令

%7s:默认表示右对齐,7表示$1输出的字符串的长度,

linux awk命令

%-7s:负号表示左对齐,如果有+号表示的不是右对齐,+号表示数值的正负属性。

操作符

awk支持算术运算。

x+y加法  x-y减法   x*y 乘法  x/y 除法  x^y 幂  x%y余运算

-x 把数值变成负数

+x 把字符串转换为数值

 

字符串操作符

没有符号的操作符,表示字符串连接

 

赋值操作符

=  

+=   sum=sum+i  sum+=i

-=   sum=sum-I   sum-=i

*=   sum*=y  sum=sum*y

/=   sum/=y  sum=sum/y

%=   sum%=y sum=sum%y

^=   sum^=y sum=sum^y

++i 是参与运算之前先让i+1

i++ 是参与运算之后再让i+1

- - 同理

 

比较操作符

>    >=    <   <=    !=    ==

 

模式匹配符

~ 左侧的字符串是否被右侧的模式(关键字)所匹配 

!~ 左侧的字符串是否不能被右侧的模式(关键字)所匹配

 

逻辑操作符

&& 与

|| 或

! 非

因为awk本身就是一个编程工具,所以其他编程工具有的功能,它基本都有

 

函数调用

内置函数rand ()

linux awk命令

这里不是要解释rand()函数,而仅仅是演示函数的调用

内置函数length() 返回指定字符串的长度

内置函数split(s,a,[r]) 以r为分隔符切割s字符串,并将切割后的结果保存在a所表示的数组中。

 

条件表达式

selector?if-true-expression:if-false-expression

selector表达式是否为真,真的话执行true语句,假的话执行false语句

 

PATTERN

类似于地址定界的功能

1、empty 空模式 匹配任意行,全内容处理

2、/regular expression/ 使用正则表达式匹配文件中的行,仅处理匹配到的行

3、relational expression 关系表达式,结果有真 有假。结果为真才会被处理。真:结果为非0值,非空字符串为真,空字符串为假。

4、line ranges 行范围 指定起始和结束行,可以使用匹配方式指定,还可以使用数字,不过要借用NR变量。

5、BEGIN\END

      BEGIN{命令行}:仅在处理文件中的文本之前执行一次

      END{命令行}:仅在处理文件中的文本之后执行一次

 

常用的action

1、expressions awk自己的语句

2、Control statements 比如 if while 控制语句

3、Compound statements组合语句

4、input statements 输入语句

5、output statements 输出语句

 

控制语句

if(condition){statements}

if(condition){statements} else {statements}

 

while(condition){statements}

 

do{statements}while(condition)

 

for(expr1;expr2) {statements}

 

switch(expr1) {case VALUE1 or /REGEXP1/:statement;case VALUE2 or /REGEXP2/:statement;default:statement}

switch类似于case 多分支 可以匹配值也可以模式匹配

 

break [n] 跳出n层循环

 

continue 停止本轮循环,继续下轮循环

 

next     awk是对文件中的每一行进行处理,next是让awk提前结束当前行的处理,继续进行下一行的处理。

 

delete array[index]

 

delete array

 

exit

 

数组

array[index-expression]

index-expression

   1、可使用任意字符串

   2、如果某数组元素事先不存在,在引用时,awk会自动创建此元素,并将其值初始化为空串。

若要判断数组中是否存在某元素,要使用”index in array”格式进行

Weekdays[“mon”]=”Monday”

若要遍历数组中的元素,需要使用for循环

 

来练习练习

1、将用户的ID做比较,UID大于1000的就是普通用户,小于1000的就是系统管理员或者系统用户

linux awk命令

2、仅处理/etc/fstab中以UUID开头的行

linux awk命令

3、仅处理不以UUID开头的行

linux awk命令

4、将用户ID作比较,UID大于1000的用户显示出来

linux awk命令

5、将/etc/passwd中bash为/bin/bash的用户显示出来

linux awk命令

linux awk命令

6、显示/etc/passwd的前10行的username和UID的行

linux awk命令

linux awk命令

linux awk命令

7、第6个例子使用printf来做

linux awk命令

8、第4个例子用awk if语句实现

linux awk命令

9、练习if  else语句

linux awk命令

10、如果用户的shell为/bin/bash,那么就输出用户名

linux awk命令

11、如果分区的使用率大于40,就显示该分区

linux awk命令

12、为指定行计算每一行的每一个字段的字符数

linux awk命令

13、在第12个例子上加个难度。小于7个字符的字符串不需要输出

linux awk命令

14、使用for再写第12例子

linux awk命令

15、输出UID为偶数的用户信息

linux awk命令

另一个种方法,使用next命令,

linux awk命令

16、在awk中使用数组

linux awk命令

17、使用for遍历数组

linux awk命令

18、统计端口监听状态的数量与种类

linux awk命令

19、统计/etc/fstab中文件系统类型出现的次数

linux awk命令

 

20、统计/etc/fstab中单子的种类和个数

linux awk命令

21、统计建立连接的客户端的IP及个数

linux awk命令

通过多个管道把需要的内容先切割出来,其实可以在特定的位置使用内建函数split

linux awk命令