5)、 AWK汇总:
5.1)AWK篇一
语法:awk 模式 动作
------------------
注意事项:
1.确保用花括号括起来动作语句,用圆括号括起来条件语句.
2.确保整个awk命令用单引号括起来
1.将文件aa打印屏幕并另存为ab
awk '{print $0}' aa | tee ab #此命令没有模式部分,动作部分必须使用花括号{}括起来
2.打印"起始部分","动作部分","结束部分"
awk 'BEGIN {print "Name\n----------"}{print $1}END{"end-of-report"}' aa
3.awk -F ":" 'BEGIN{print "用户名\t用户ID\n--------------"}{print $1 "\t" $3}' aa
用户名 用户ID
--------------
root 0
bin 1
daemon 2
4.条件匹配,搜索$1为/root的行
awk '{if($1~/root/)print $0}' aa
5.匹配第一列为root
[root@class16 ~]# awk -F ":" '{if($1~/root/)print $0}' aa
root:x:0:0:root:/root:/bin/bash
或者是
[root@class16 ~]# awk -F ":" '$1=="root" {print $0}' aa
root:x:0:0:root:/root:/bin/bash
6.$4列比$3列数字大的现实出来
[root@class16 ~]# awk -F ":" '{if($4>$3) print $0}' aa
bin:x:1:21:bin:/bin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:27:lp:root:/var/spool/lpd:/sbin/nologin
7.查询大小写字母
[root@class16 ~]# awk '/[rR]oot/' aa
root:x:0:0:root:/root:/bin/bash
daemon:xroot:2:2:daemon:/sbin:/sbin/nologin
lp:x:4:27:lp:root:/var/spool/lpd:/sbin/nologin
Rootadm:x:23:4:adm:/var/adm:/sbin/nologin
8.抽取任意字母;从aa文件中抽取第一列为四个字符串,最后一个字符为a
awk '{$1 ~^...a}' aa
9.或关系抽取
[root@class16 ~]# awk '$0 ~/(root|ROOT)/' aa
root:x:0:0:root:/root:/bin/bash
daemon:xroot:2:2:daemon:/sbin:/sbin/nologin
lp:x:4:27:lp:root:/var/spool/lpd:/sbin/nologin
或者是
[root@class16 ~]# awk '$0 ~/(root|ROOT)/' aa
root:x:0:0:root:/root:/bin/bash
daemon:xroot:2:2:daemon:/sbin:/sbin/nologin
lp:x:4:27:lp:root:/var/spool/lpd:/sbin/nologin
[root@class16 ~]#
10.AWK内置变量
ARGC 命令行参数个数
ARGV 命令行参数排列
NR 已读的记录数
NF 浏览记录的域个数
[root@class16 ~]# awk '{print NF,NR,$0}END{print FILENAME}' aa
1 1 root:x:0:0:root:/root:/bin/bash
1 2 bin:x:1:21:bin:/bin:/sbin/nologin
1 3 daemon:xroot:2:2:daemon:/sbin:/sbin/nologin
aa
[root@class16 ~]#
11.如果aa文件的记录数大于0,并且第一列匹配root后才打印$0
[root@class16 ~]# awk '{if(NR>0 && $1~/root/)print $0}' aa
root:x:0:0:root:/root:/bin/bash
daemon:xroot:2:2:daemon:/sbin:/sbin/nologin
lp:x:4:27:lp:root:/var/spool/lpd:/sbin/nologin
[root@class16 ~]#
12.使用NF打印当前目录的最后一个位置
[root@class16 network-scripts]# pwd
/etc/sysconfig/network-scripts
[root@class16 network-scripts]# echo $PWD| awk -F "/" '{print $NF}'
network-scripts
[root@class16 network-scripts]#
13.使用名称替换打印
[root@class16 ~]# awk -F ":" '{name=$1;login=$7;if(login~/\/sbin\/nologin/) print name " is not login system"}' aa
bin is not login system
daemon is not login system
adm is not login system
adm is not login system
bin is not login system
daemon is not login system
14.定义一个变量BASELINE;当第七列等价于BASELINE时候,打印$0
[root@class16 ~]# awk -F ":" 'BEGIN {BASELINE="/bin/bash"} {if($7==BASELINE)print $0}' aa
root:x:0:0:root:/root:/bin/bash
15.如果$1为root,则将$1改为"root_jack";打印所有行
[root@class16 ~]# awk -F ":" '{if($1=="root")($1="root_jack");print $1}' aa #注意条件后面的分号
root_jack
bin
daemon
[root@class16 ~]#
16.如果$1为root,则将$1改为"root_jack";打印修改的行
[root@class16 ~]# awk -F ":" '{if($1=="root"){$1="root_jack";print $1}}' aa
root_jack
[root@class16 ~]#
17.打印指定行,并且创建一个新域$8
[root@class16 ~]# awk -F ":" 'BEGIN{print "用户名\t\tID\n-------- ----"}{if($3<=$4){$8=$4-$3} print $1"\t\t"$8}' aa
用户名 ID
-----------------------
root 0
bin 20
daemon 0
[root@class16 ~]#
18.定义过滤的值
[root@class16 ~]# df -k | awk '($4~/^[0-9]/) {if($4<Tr) print $6"\t"$4}' Tr=56000
/mnt 0 #次行为显示结果
[root@class16 ~]#
19. 定义变量过滤
[root@class16 ~]# who | awk '{if($1==user)print $1 " you are connected to "$2}' user=$LOGNAME
root you are connected to tty1
20.使用脚本方式编写
[root@class16 ~]# cat au.awk
#!/bin/awk -f
BEGIN{FS=":"}
{print $1,"\t",$5}
[root@class16 ~]#
21.去除file文件中重复的内容,并统计个数:
awk '{a[$0]++} END{for(i in a)print i,a[i]}' file | sort
5.2)AWK篇二
!~ 不匹配正则表达式
~ 匹配正则表达式
++x #在返回x值之前,x变量加1
x++ #在返回x值之后,x变量加1
一: awk中使用shell中的变量 "'$var'"
例如:
var="test"
awk 'BEGIN{print "'$var'"}'
将双括号变为单括号的常量,传递给了awk.
如果var中含空格,为了shell不把空格作为分格符,便应该如下使用:
var="this is a test"
awk 'BEGIN{print "'"$var"'"}'
二: export 变量,使用ENVIRON["var"]形式,获取环境变量的值
例如:
var="this is a test"; export var;awk 'BEGIN{print ENVIRON["var"]}'
三: 可以使用awk的-v选项 (如果变量个数不多,个人偏向于这种写法)
例如:
var="this is a test"
awk -v awk_var="$var" 'BEGIN {print awk_var}’
这样便把系统变量var传递给了awk变量awk_var.
四:awk向shell变量传递值
"由awk向shell传递变量",其思想无非是用awk(sed/perl等也是一样)输出若干条shell命令,然后再用shell去执行这些命令。
eval $(awk 'BEGIN{print "var1='str1';var2='str2'"}')
或
eval $(awk '{printf("var1=%s; var2=%s; var3=%s;",$1,$2,$3)}’ abc.txt)
之后可以在当前shell中使用var1,var2等变量了。
echo "var1=$var1 —– var2=$var2"
五: 模式匹配
使用正则表达式~符合
awk 'BEGIN {FS=":"} $1~/root/' /etc/passwd
-------------- ----------
模式匹配 动作部分
--------------------------------------------------------
1.gsub(r,s) #在输入文件中用s替换r
例如:awk 'gsub(/root/,"AAA"){print $0}' /etc/passwd
AAA:x:0:0:AAA:/AAA:/bin/bash
operator:x:11:0:operator:/AAA:/sbin/nologin
2.gsub(r,s,t) #在t中用s替换r
例如:awk 'BEGIN{FS=":";OFS=":"} gsub(/root/,"JACK",$1)' /etc/passwd
JACK:x:0:0:root:/root:/bin/bash
3.index(s,t) #返回s中字符串第一个t的位置
例如:awk 'BEGIN{print index("abcdefgfasdgsdgsgdf","f")}'
4.length() #返回字符串长度
例如:awk 'BEGIN{print index("hello")}'
5.match(s,t) #测试s是否包含匹配t的字符串,返回匹配的位置
例如:awk 'BEGIN{print match("aaarootbbbbbb",/root/)}'
6.sub(r,s,t) #将t中第1次出现的r替换为s,r可以为正则表达式.
例如:awk 'BEGIN{str="aaaaaabbccccccddddee";sub(/bb/,"JACK",str); printf("%s\n",str)}'
aaaaaaJACKccccccddddee
7.substr(str,起始位置,结束位置)
awk 'BEGIN{str="192.168.1.10 Bacast";print substr(str,0,12)}'
192.168.1.10
或
substr(str,起始位置)
例如:awk 'BEGIN{str="192.168.1.10 Bacast";print substr(str,10)}'
8.判断元素是否在数组中
index in array
例如:awk 'BEGIN{data[10.15]="12";if("10.15" in data)print "hello"}'
9.split函数
split(r,s,t) #将字符串以t为分隔符,将r字符串拆分成字符串数组,并存放在t中.split函数返回值是数组的大小
例如:awk 'BEGIN{print split("abc/def/xyz",str,"/")}'
3
10. 如果要对Shell命令结果进行处理,必须将结果通过管道传给getline函数,如果结果多的话,需要使用循环
awk 'BEGIN{while( ("ls /usr" | getline d) >0) print d}'
5.3)awk高级篇
#文件去重:
awk '!a[$0]++' file
#输出重复的行
awk 'a[$0]++' file
分析:
如果是第一次出现a[$0]++的值为0(假),而!a[$0]++的值就为1(真),之后就执行print $0
第二次或者两次以上的出现a[$0]++的值就为大于0的整数值(真),
例如1,2,3...,而!a[$0]++的值就为0(假),之后就不执行print $0操作
#pattern为!($0 in a),Action为{a[$0];print $0}
awk '!($0 in a) {a[$0];print $0}'
分析:
1.执行第一行时的a的数组为空,($0 in a)为假,!($0 in a)为真。执行Action,a[$0]就存在了a[row1],打印第一行
2.执行第二行时的a的数组为a[row1],如果a[row2] 是a[$0]中的元素,!($0 in a)为真为假,不执行Ation。
如果a[row2]不是a[$0]中的元素,执行Action,a[$0]中增加元素(a[row1],a[row2]),打印第二行。
3.重复执行类似的第二步骤。达到的去重的效果。
[root@Mail ~]# awk -F: '{printf "% -12s % -6s % -10s\n",$1,$2,$NF}' /etc/passwd | head -5
root x /bin/bash
bin x /sbin/nologin
daemon x /sbin/nologin
adm x /sbin/nologin
lp x /sbin/nologin
[root@Mail ~]#