Linux-shell-AWK

awk处理过程: 依次对每一行进行处理的结果

awk  [-F|-f|-v]  ‘BEGIN{}  //{command1; command2}  END{}’  file
 [-F|-f|-v] :-F指定分隔符,-f调用脚本,-v定义变量 var=value
BEGIN   初始化代码块,在对每一行进行处理之前,初始化代码,主要是引用全局变量,设置FS分隔符
//           匹配代码块,可以是字符串或正则表达式
END      结尾代码块,在对每一行进行处理之后再执行的代码块,主要是进行最终计算或输出结尾摘要信息
 
特殊含义:
OFS ----输出字段分隔符, 默认也是空格
    $0----表示整行所有数据
    $1---- 每行第一个字段(列)
   NF---- 字段数量(分隔后的列数);$NF最后一列 '{print $NF}'  打印最后一列
   NR---- 行号;NR==1代表第一行   'NR==1{print $2}' 打印第一行第二列
~            匹配字符
!~           不匹配字符
==         等于
!=           不等于
&&      逻辑与
||             逻辑或
+            匹配时表示1个或1个以上
-F  '[:#/]'   定义三个分隔符

[root@k8s-master ~]# echo "root x:0?0:root:/root:/bin/bash" | awk -F '[:?/]' '{print $3 }'  #将:?/三个同时做分隔符
0

[root@k8s-master ~]# echo "root x:0?0:root:/root:/bin/bash" | awk -F '[:?/]' '{print $8 }'
bin

awk -F:    等价于awk -F  ":"

[root@k8s-master python-shell]# ll xx
-rw-r--r--. 1 root root 528 Nov 12 11:39 xx
[root@k8s-master python-shell]# ll xx | awk '{print NF}'  ##NF打印的是分割之后的列数之和
9
[root@k8s-master python-shell]# ll xx | awk '{print $NF}'  ##$NF打印的是最后一列值
xx
[root@k8s-master python-shell]#

1、awk  -F: '{print $1,$3,$6}' OFS="|" /etc/passwd 
将/etc/passwd的第一、三、六列内容打印出来,并且以“|”分割

2、awk '{print}'  /etc/passwd   ==   awk '{print $0}'  /etc/passwd  

加不加$0,都是打印整行内容

3、[root@k8s-master ~]# awk '{print "a"}' /etc/passwd >>ren

passwd有多少行,就会往ren里面写多少行a;每行都是一个a
4、[root@k8s-master ~]# awk -F: 'NR==1{print $1; print $2}'   /etc/passwd 
将第一行的以:分割后的字符串,第一个字段、第二个字段分两行显示

5、awk -F":" '(NR==1){print $1" "$3}' /etc/passwd 等价于 awk -F":" '(NR==1){print $1,$3}' /etc/passwd     每个字段中间会有空格

6、每个字符间没有空格,直接相连

[root@k8s-master ~]# awk -F":"  'NR==1,NR==3{print $1 $3}'  /etc/passwd  #打印第一行和第三行的

[root@k8s-master ~]# awk -F":" '(NR==1){print $1 $3}'  /etc/passwd  

[root@k8s-master ~]# awk -F":" '(NR==1){print $1$3}'  /etc/passwd 

[root@k8s-master ~]# awk -F":" '(NR==1){print $1""$3}'  /etc/passwd 

 7、打印第五行和第六行

[root@k8s-master ~]# awk -F: 'NR==5 || NR==6{print}' /etc/passwd

[root@k8s-master ~]# awk 'NR!=1{print}'  /etc/passwd  #除了第一行不打印

[root@k8s-master ~]# awk -F ":" 'NR>9{print $0}' /etc/passwd  #打印第九行之后的内容

[root@k8s-master ~]# awk -F ":" 'NF>9{print $0}' /etc/passwd #打印字段数(列数)大于9的所有行

 [root@k8s-master ~]# awk '{print NR,$0}' /etc/passwd   #打印行号和内容

[root@k8s-master ~]# awk -F: '{print $NF}' /etc/passwd  #打印每行的最后一列

[root@k8s-master ~]# awk -F: '{print NF}' /etc/passwd   #打印每行有多少列(以冒号分割后)

8、字符匹配

/**/纯字符匹配   !/**/纯字符不匹配   ~/**/字段值匹配    !~/**/字段值不匹配   ~/a1|a2/字段值匹配a1或a2

[root@k8s-master ~]# awk '/postfix/' /etc/passwd

[root@k8s-master ~]# awk '/postfix/{print}' /etc/passwd

[root@k8s-master ~]# awk '/postfix/{print $0}' /etc/passwd  #以上三个命令一样,都是打印匹配到postfix的行

[root@k8s-master ~]# awk '/^postfix/' /etc/passwd  #打印postfix开头的行

[root@k8s-master ~]# awk '/postfix$/' /etc/passwd  #打印postfix结尾的行

[root@k8s-master ~]# awk '!/postfix/{print $0}' /etc/passwd  #打印不包含postfix的所有行

[root@k8s-master ~]# awk '/postfix|etcd/{print $0}' /etc/passwd  #打印匹配到postfix或者etcd的行

 [root@k8s-master ~]# awk '!/postfix|etcd/{print $0}' /etc/passwd  #打印不包含postfix或者etcd的行

[root@k8s-master ~]# awk '/postfix/,/etcd/{print $0}' /etc/passwd  #打印匹配到postfix的行,一直到匹配到etcd所在的行

[root@k8s-master ~]# awk -F: '{if($1~/etcd/) print $1}' /etc/passwd   

[root@k8s-master ~]# awk -F: '$1~/etcd/{print $1}' /etc/passwd   #和上面等价,当用冒号分割后,第一列如果匹配到包含etcd,就打印第一列内容

[root@k8s-master ~]# awk -F: '$1!~/etcd/{print $1}' /etc/passwd

[root@k8s-master ~]# awk -F: '$1!~/mail|mysql/{print $1}' /etc/passwd   #分割后,打印第一列不包含mail或者mysql的所有行的第一列

9、IF语句

IF语句:必须用在{}中,且比较内容用()扩起来

[root@k8s-master ~]# awk -F: '{if($1~/etcd/) print $1}' /etc/passwd

[root@k8s-master ~]# awk -F: '{if($1~/etcd/) {print $1}}'  /etc/passwd  #以上两个等价

[root@k8s-master ~]# awk -F: '{if($1~/etcd/) {print $1} else {print $2}}' /etc/passwd  #分割后,如果第一列包含etcd,则打印所有行第一列,否则打印第二列

 

 

 10、条件表达式 ==   !=   >   >=  

[root@k8s-master ~]# awk -F":" '$1=="etcd"{print $3}' /etc/passwd
998
[root@k8s-master ~]# awk -F":" '{if($1=="etcd") print $3}' /etc/passwd   #如果第一列是etcd,则打印第三列
998
[root@k8s-master ~]

[root@k8s-master ~]# awk -F":" '$1!="etcd"{print $3}' /etc/passwd #分割后,打印第一列不是etcd,所在行的第三列

[root@k8s-master ~]# awk -F":" '$3>1000{print $3}' /etc/passwd   #分割后,打印第一列大于1000,所在行的第三列

[root@k8s-master ~]# awk -F":" '$3>=100{print $3}' /etc/passwd  #分割后,打印第一列大于等于100,所在行的第三列

[root@k8s-master ~]# awk -F":" '$3<1{print $3}' /etc/passwd     #分割后,打印第一列小于1,所在行的第三列

[root@k8s-master ~]# awk -F":" '$3<=1{print $3}' /etc/passwd  #分割后,打印第一列小于等于1,所在行的第三列

11、逻辑运算符 && || 

[root@k8s-master ~]# awk -F: '$1~/etcd/ && $3>8 {print }' /etc/passwd   # 分割后,第一列匹配etcd,并且$3>8,打印整行

etcd:x:998:994:etcd user:/var/lib/etcd:/sbin/nologin

[root@k8s-master ~]# awk -F: '{if($1~/etcd/ && $3>8) print }' /etc/passwd # 分割后,第一列匹配etcd,并且$3>8,打印整行
etcd:x:998:994:etcd user:/var/lib/etcd:/sbin/nologin

[root@k8s-master ~]# awk -F: '$1~/etcd/ || $3>1000 {print }' /etc/passwd  # 分割后,第一列匹配etcd,或者$3>1000,打印整行
etcd:x:998:994:etcd user:/var/lib/etcd:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
[root@k8s-master ~]# awk -F: '{if($1~/etcd/ || $3>1000) print }' /etc/passwd  # 分割后,第一列匹配etcd,或者$3>1000,打印整行
etcd:x:998:994:etcd user:/var/lib/etcd:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
[root@k8s-master ~]#

12、数值运算

 [root@k8s-master ~]# awk -F: '$3 > 100 || $3 < 5' /etc/passwd   #分割后第三列大于100或者第三列小于5

[root@k8s-master ~]# awk -F: '$3+$4 > 200' /etc/passwd    #分割后第三列和第四列之和大于200得行

[root@k8s-master ~]# awk -F: '/mysql|mail/{print $3+10}' /etc/passwd  #分割后匹配mysql或者mail的行,将第三列的和加10

18
[root@k8s-master ~]# awk -F: '/mysql|mail/{print $0}' /etc/passwd
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
[root@k8s-master ~]# awk -F: '/etcd/{print $3-$4}' /etc/passwd  #做减法

[root@k8s-master ~]# awk -F: '/etcd/{print $3*$4}' /etc/passwd #乘法

[root@k8s-master ~]# awk '/MemFree/{print $2/1024}' /proc/meminfo   #除法

[root@k8s-master ~]# awk '/MemFree/{print int($2/1024)}' /proc/meminfo   #取整

格式化输出:

netstat -anp|awk '{printf "%-8s %-8s %-10s\n",$1,$2,$3}' 
printf表示格式输出
%格式化输出分隔符
-8长度为8个字符
s表示字符串类型
打印每行前三个字段,指定第一个字段输出字符串类型(长度为8),第二个字段输出字符串类型(长度为8)
IF语句
awk -F: '{if($3>100) print "large"; else print "small"}' /etc/passwd
awk -F: '{if($3<100) next; else print}' /etc/passwd                         //小于100跳过,否则显示
awk -F: 'BEGIN{i=1} {if(i<NF) print NR,NF,i++ }' /etc/passwd   
awk -F: 'BEGIN{i=1} {if(i<NF) {print NR,NF} i++ }' /etc/passwd
另一种形式
awk -F: '{print ($3>100 ? "yes":"no")}'  /etc/passwd 
awk -F: '{print ($3>100 ? $3":\tyes":$3":\tno")}'  /etc/passwd
while语句
awk -F: 'BEGIN{i=1} {while(i<NF) print NF,$i,i++}' /etc/passwd
awk -F: '{print NR,$1,$2,$3,$4,$5}' OFS='\t' helloworld.sh           //制表符分隔输出前5个字段,并打印行号

 

AWK语法:

BEGIN{}这个特殊的pattern最常用的就是 变量赋值。 BEGIN这个pattern就是文件没开始读的时候 执行

Pattern模式:BEGIN 和 END。
BEGIN 模式指定了处理文本之前需要执行的操作:END 模式指定了处理完所有行之后所需要执行的操作

通常使用BEGIN来显示变量和预置(初始化)变量,使用END来输出最终结果

[root@k8s-master ~]# awk 'BEGIN{x=0};/\/sbin\/nologin$/{x++};END{print x}' /etc/passwd  #统计以/sbin/nologin结尾的行的行数
25

awk ‘BEGIN {print “BEGIN” ,“BEGIN” } { print $1,$2 }’ 1.txt  

先执行BEGIN{},如果有要处理的文件,就继续执行BEGIN{}后面的{}中的内容

 awk 'BEGIN {FS=":"} {printf("%3s | %15s | %s\n",$1,$2,$6)}' ./password.ls

{FS=":"} #先定义一个分隔符

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

[root@k8s-master ~]# awk -F: '/bash$/{print}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
rencs:x:1000:1001::/home/rencs:/bin/bash
[root@k8s-master ~]# awk -F: '/bash$/{print $1}' /etc/passwd
root
rencs
[root@k8s-master ~]# awk -F: '/bash$/{print $1 |"wc -l"}' /etc/passwd  #统计个数
2

[root@k8s-master ~]# awk -F. 'BEGIN{"hostname" | getline;{print $1}}'
k8s-master
[root@k8s-master ~]# awk -F. 'BEGIN{"hostname" | getline;print $1}'
k8s-master
[root@k8s-master ~]#

posted @ 2021-09-10 00:39  闲云野鹤cs  阅读(97)  评论(0编辑  收藏  举报