awk高级应用

命令格式:

awk  [-F | -f | -v ] ‘BEGIN {} / / {command1;command2} END {}’file

       -F           指定分隔符

       -f           调用脚本

       -v           定义变量

     ‘{}’      引用代码块

       {…}        命令代码块,包含一条或多条命令

       BEGIN    初始化代码块

       / str /            匹配代码块,可以是字符串或正则表达式

       {print A;print B}         多条命令使用分号分隔

       END       结尾代码块

在awk中,pattern有以下几种:

1)  empty空模式,这个也是我们常用的

2)  /regular expression/  仅处理能够被这个模式匹配到的行

例:打印以root开头的行

[root@xuegod63 ~]# awk -F: '/^root/{print $0}' /etc/passwd

root:x:0:0:root:/root:/bin/bash

 

3) 行范围匹配 startline,endline

例1:输出行号大于等于3且行号小于等于6的行

[root@xuegod63 ~]# awk -F: '(NR>=3&&NR<=6){print NR,$0}' /etc/passwd

3 daemon:x:2:2:daemon:/sbin:/sbin/nologin

4 adm:x:3:4:adm:/var/adm:/sbin/nologin

5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

6 sync:x:5:0:sync:/sbin:/bin/sync

内置变量的特殊用法:

ü  $0       表示整个当前行

ü  NF     字段数量    NF(Number 数量 ;  field 字段)

ü  NR      每行的记录号,多文件记录递增   Record [ˈrekɔ:d]

ü  \t        制表符

ü  \n      换行符

ü  ~        匹配

ü  !~      不匹配

ü  -F'[:#/]+'  定义三个分隔符

 

例1:使用NR行号来定位,然后提取IP地址

注:这个思路很好,之前都是通过 过滤关键字来定位,这次是通过行号,多了一种思路

[root@xuegod63 ~]# ifconfig ens33 | awk -F " " 'NR==2{print $2} '

192.168.1.63

注:NR==2表示行号

例2:NR与FNR的区别

[root@xuegod63 ~]# awk '{print NR"\t" $0}' /etc/hosts /etc/hostname

1     127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4

2     ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

3     192.168.1.63   xuegod63.cn

4     192.168.1.64   xuegod64.cn

5     192.168.1.64   xuegod62.cn

6    

7     xuegod63.cn

[root@xuegod63 ~]# awk '{print FNR"\t" $0}' /etc/hosts /etc/hostname

1     127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4

2     ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

3     192.168.1.63   xuegod63.cn

4     192.168.1.64   xuegod64.cn

5     192.168.1.64   xuegod62.cn

6    

1     xuegod63.cn

注:对于NR来说,在读取不同的文件时,NR是一直加的 ;

对于FNR来说,在读取不同的文件时,它读取下一个文件时,FNR会从1开始重新计算的

 

例3:使用3种方法去除首行

方法1:[root@xuegod63 ~]# route -n | grep -v ^Kernel

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface

0.0.0.0         192.168.1.1     0.0.0.0         UG    100    0        0 ens33

192.168.1.0     0.0.0.0         255.255.255.0   U     100    0        0 ens33

192.168.122.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr0

方法2:sed  1d #删除第1行的内容

[root@xuegod63 ~]# route -n | sed 1d

方法3: awk

[root@xuegod63 ~]# route -n | awk 'NR!=1 {print $0}'

 

例4:匹配,使用awk查出以包括root字符的行 , 有以下3种方法

[root@xuegod63 ~]# awk -F: "/root/{print}" /etc/passwd

[root@xuegod63 ~]# awk -F: "/root/" /etc/passwd

[root@xuegod63 ~]# awk -F: '/root/{print $0}' /etc/passwd

做一个不匹配root行:

[root@xuegod63 ~]# awk -F: '!/root/{print $0}' /etc/passwd

以root开头的行:

[root@xuegod63 ~]# awk -F: '/^root/{print $0}' /etc/passwd

以bash结尾的行:

[root@xuegod63 ~]# awk -F: '/bash$/{print $0}' /etc/passwd

root:x:0:0:root:/root:/bin/bash

mk:x:1000:1000:mk:/home/mk:/bin/bash

 

 

=====以下知识,大家了解一下======

例5:条件表达式

表达式?if-true:if-false 问号前面是条件,如果条件为真执行if-true,为假执行if-false

例1:如果passwd中UID小于10,则给变量USER赋值成aaa,否则赋值成bbb

[root@xuegod63 ~]# awk -F: '{$3<10? USER="aaa":USER="bbb";print $1,USER}' /etc/passwd

root aaa

bin aaa

daemon aaa

adm aaa

lp aaa

sync aaa

shutdown aaa

halt aaa

mail aaa

operator bbb

。。。

 

用if(条件){命令1;命令2}elif(条件){命令;}else{命令}中,在比较条件中用( )扩起来,在AWK中,如果条件为1为真,0为假

例:如果UID大于10 ,则输出user=>用户名,否则输出pass=>用户名

[root@xuegod63 ~]# awk -F: '{if($3<10){print "user=>"$1}else{print "pass=>"$1}}' /etc/passwd

user=>root

user=>bin

user=>daemon

user=>adm

user=>lp

user=>sync

user=>shutdown

user=>halt

user=>mail

pass=>operator

 

~        匹配

!~      不匹配

例:查出行号小于等于5且包括bin/bash的行

[root@xuegod63 ~]#  awk -F: '{if($3<=5 && $NF ~ "bin/bash"){print $1,$NF}}' /etc/passwd

root /bin/bash

 

例6:变量

1)   用-v指定  var=value 变量名区分大小写的

2)   在程序中直接定义

3)   在awk里,使用变量不用加$符号。

[root@xuegod63 ~]# var="test"

[root@xuegod63 ~]# awk 'BEGIN{print "'$var'"}'  #引用变量时,使用单引号+双引号括起来

test

 

例7:格式化输出

printf命令:格式化输出  printf “FORMAT”,item1,item2.......

format使用注意事项:

1、其与print命令的最大不同是,printf需要指定format样式

2、format用于指定后面的每个item的输出格式

3、printf语句不会自动打印换行符;\n

4、format格式的指示符都以%开头,后跟一个字符;如下:

%c: 显示字符的ASCII码

%d, %i:十进制整数

%e, %E:科学计数法显示数值

%f: 显示浮点数

%g, %G: 以科学计数法的格式或浮点数的格式显示数值;

%s: 显示字符串

%u: 无符号整数

%%: 显示%自身

例1:输入passwd文件中的第1列内容,输出时不会换行

[root@xuegod63 ~]#  awk -F: '{printf "%s",$1}' /etc/passwd  ##不会自动换行

rootrootbindaemonadmlpsyncshutdownhaltmailoperatorgamesftpnobodysystemd-networkdbuspolkitdabrtlibstoragemgmtrpccolordsaslauthrtkitchronyqemutssusbmuxdgeocluerpcusernfsnobodyradvdsetroubleshootpulsegdmgnome-initial-setupsshdavahipostfixntptcpdumpmk[root@xuegod63 ~]#

例2:换行输出

[root@xuegod63 ~]# awk -F: '{printf "%s\n",$1}' /etc/passwd


例3:在输出的字母前面添加自定义字符串USERNAME:

[root@xuegod63 ~]# awk -F: '{printf "USERNAME: %s\n",$1}' /etc/passwd  

USERNAME: root

USERNAME: bin

USERNAME: daemon

USERNAME: adm


例4:对$1和$NF都做格式化输出

[root@xuegod63 ~]# awk -F: '{printf "USERNAME: %s %s\n",$1,$NF}' /etc/passwd

USERNAME: root /bin/bash

USERNAME: bin /sbin/nologin

USERNAME: daemon /sbin/nologin


例5:对$1和$NF都做格式化输出,在$1和$NF两者之间添加一串====字符进行输入

[root@xuegod63 ~]# awk -F: '{printf "USERNAME: %s=========%s\n",$1,$NF}' /etc/passwdUSERNAME: root=========/bin/bash

USERNAME: bin=========/sbin/nologin

 

awk修饰符:

N: 显示宽度;

-: 左对齐;

一个字母占一个宽度。默认是右对齐

 

例1:显示时用10个字符串右对齐显示。如果要显示的字符串不够10个宽度,以字符串的左边自动添加。一个字母占一个宽度。默认是右对齐

[root@xuegod63 ~]# awk -F":" '{printf "%10s\n",$1}'  /etc/passwd                                              image.png

例2:使用10个宽度,左对齐显示

[root@xuegod63 ~]# awk -F":" '{printf "%-10s\n",$1}'  /etc/passwd

image.png

例3:第1列使用15个字符宽度左对齐输出最后一列使用15个字符宽度右对齐输出

[root@xuegod63 ~]# awk -F: '{printf "USERNAME: %-15s %15s\n",$1,$NF}' /etc/passwd

USERNAME: root                  /bin/bash

USERNAME: bin               /sbin/nologin

image.png

例4:使用开始和结束模块来格式化输出

[root@xuegod63 ~]# cat test.awk

BEGIN{

       print "UserId\t\t\tShell"

       print "-------------------------------"

       FS=":"

       }

$3>=500 && $NF=="/sbin/nologin"{

       printf "%-20s %-20s\n", $1,$NF 

       }

END{

       print "--------------------------------"

       }

[root@xuegod63 ~]# awk -f test.awk /etc/passwd

UserId                  Shell

-------------------------------

polkitd              /sbin/nologin      

libstoragemgmt       /sbin/nologin      

colord               /sbin/nologin      

saslauth             /sbin/nologin      

chrony               /sbin/nologin      

geoclue              /sbin/nologin      

nfsnobody            /sbin/nologin      

setroubleshoot       /sbin/nologin      

gnome-initial-setup  /sbin/nologin      

--------------------------------

 

版权声明:
作者:WaterBear
链接:https://l-t.top/1674.html
来源:雷霆运维
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>