shell文本处理工具awk
awk是一个强大的文本分析工具,运行效率高,而且代码简单,对格式化的文本处理能力超强。awk有3个不同版本: awk、nawk和gawk,未作特别说明,一般指gawk,gawk是AWK的GNU版本。
语法:
awk命令形式:
[-F|-f|-v] 大参数,-F指定分隔符,-f调用脚本,-v定义变量 var=value
' ' 引用代码块
BEGIN 初始化代码块,在对每一行进行处理之前,初始化代码,主要是引用全局变量,设置FS分隔符.
// 匹配代码块,可以是字符串或正则表达式
{} 命令代码块,包含一条或多条命令
; 多条命令使用分号分隔
END 结尾代码块,在对每一行进行处理之后再执行的代码块,主要是进行最终计算或输出结尾摘要信息
特殊要点:
$0 表示整个当前行
$1 每行第一个字段
NF 字段数量变量
NR 每行的记录号,多文件记录递增
FNR 与NR类似,不过多文件记录不递增,每个文件都从1开始
\t 制表符
\n 换行符
FS BEGIN时定义分隔符
RS 输入的记录分隔符, 默认为换行符(即文本是按一行一行输入)
~ 匹配,与==相比不是精确比较
!~ 不匹配,不精确比较
== 等于,必须全部相等,精确比较
!= 不等于,精确比较
&& 逻辑与
|| 逻辑或
+ 匹配时表示1个或1个以上
/[0-9][0-9]+/ 两个或两个以上数字
/[0-9][0-9]*/ 一个或一个以上数字
FILENAME 文件名
OFS 输出字段分隔符, 默认也是空格,可以改为制表符等
ORS 输出的记录分隔符,默认为换行符,即处理结果也是一行一行输出到屏幕
-F'[:#/]' 定义三个分隔符
[root@localhost scripts]# cat /etc/passwd |awk -F : '{print $1}'
root
bin
daemon
adm
awk工作流程是这样的:读入有'\n'换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,$0则表示所有域,$1表示第一个域,$n表示第n个域。默认域分隔符是"空白键" 或 "[tab]键",所以$1截取了用户这列.
awk '{print}' /etc/passwd #awk '{print $0}' /etc/passwd
[root@localhost scripts]# awk 'END{ print NR }' /etc/passwd ##统计行号
19
[root@localhost scripts]# awk -F ":" '{print $1;print $2}' /etc/passwd #打印每行的前两个字符串,分行输出
root
x
bin
x
daemon
x
adm
x
[root@localhost scripts]# awk -F ":" '{print $1,$2,$3}' OFS="\t" /etc/passwd ## 打印字段$1,$2,$3.并以制表符分割。
root x 0
bin x 1
daemon x 2
adm x 3
lp x 4
sync x 5
shutdown x 6
halt x
[root@localhost scripts]# awk -F ":" '{print $1,$2,$3}' OFS=" " /etc/passwd ## 打印字段$1,$2,$3.并以空格分割
root x 0
bin x 1
daemon x 2
adm x 3
lp x 4
sync x 5
shutdown x 6
halt x 7
[root@localhost scripts]# awk -F: '{print $1" "$3}' /etc/passwd ## 手动添加空格
root 0
bin 1
daemon 2
adm 3
[root@localhost scripts]# awk -F: 'NF==4 {print}' /etc/passwd ##显示行中只有四个字段的行 [root@localhost scripts]# awk -F: 'NF<6 {print}' /etc/passwd ##打印行中字段数小于6个的行 [root@localhost scripts]# awk -F: 'NF>2{print $0}' /etc/passwd ##显示每行字段数量大于2的行 [root@localhost scripts]# awk '{print NR,$0}' /etc/passwd ##输出每行的行号
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
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
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8 halt:x:7:0:halt:/sbin:/sbin/halt
9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10 uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
[root@localhost scripts]# awk -F: '{print NR,NF,$NF,"\t",$0}' /etc/passwd ##输出每行的行号,字段数,最后一个字段,制表符,全行内容
1 7 /bin/bash root:x:0:0:root:/root:/bin/bash
2 7 /sbin/nologin bin:x:1:1:bin:/bin:/sbin/nologin
3 7 /sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 7 /sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin
5 7 /sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 7 /bin/sync sync:x:5:0:sync:/sbin:/bin/sync
7 7 /sbin/shutdown shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8 7 /sbin/halt halt:x:7:0:halt:/sbin:/sbin/halt
9 7 /sbin/nologin mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10 7 /sbin/nologin uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
11 7 /sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin
[root@localhost scripts]# awk 'NR==6{print}' /etc/passwd ##打印出第六行的内容
sync:x:5:0:sync:/sbin:/bin/sync
[root@localhost ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/VolGroup-lv_root 8.5G 1.1G 7.0G 14% /
tmpfs 238M 0 238M 0% /dev/shm
/dev/sda1 485M 33M 427M 8% /boot
[root@localhost ~]# df -h|awk 'NR!=1{print}' ##不显示第一行
/dev/mapper/VolGroup-lv_root 8.5G 1.1G 7.0G 14% /
tmpfs 238M 0 238M 0% /dev/shm
/dev/sda1 485M 33M 427M 8% /boot
//纯字符匹配 !//纯字符不匹配 ~//字段值匹配 !~//字段值不匹配 ~/a1|a2/字段值匹配a1或a2
[root@localhost ~]# awk '/root/' /etc/passwd root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin [root@localhost ~]# awk '/root/{print }' /etc/passwd root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin awk '!/root/{print $0}' /etc/passwd ##不匹配root awk '!/root/' /etc/passwd
[root@localhost ~]# awk '/nobody|sshd/{print}' /etc/passwd ##匹配两个字段
nobody:x:99:99:Nobody:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
or
[root@localhost ~]# grep -E 'nobody|sshd' /etc/passwd
nobody:x:99:99:Nobody:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
[root@localhost ~]# awk '/nobody/,/sshd/{print}' /etc/passwd ##匹配区域之间
nobody:x:99:99:Nobody:/:/sbin/nologin
vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
saslauth:x:499:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
or
[root@localhost ~]# sed -n '/nobody/,/sshd/p' /etc/passwd
nobody:x:99:99:Nobody:/:/sbin/nologin
vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
saslauth:x:499:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
[root@localhost ~]# awk -F: '{if($1~/mail/){print $1} else {print $2}}' /etc/passwd ##加入if判断到语句中。
x
x
x
mail
x
[root@localhost ~]# awk -F: '{if(NF~7){print $NR} else{print $1}}' /etc/passwd
root
x
2
4
lp
/sbin
/sbin/shutdown
[root@localhost ~]# awk -F: '{if(NF~7){print $1}}' /etc/passwd
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
uucp
operator
条件表达式
==
[root@localhost ~]# awk -F: '$1=="root"{print $3}' /etc/passwd 0 [root@localhost ~]# awk -F: '{if($1=="root")print $3}' /etc/passwd 0 [root@localhost ~]# awk -F: '{if($1~"root")print $3}' /etc/passwd 0 [root@localhost ~]# awk -F: '{if($1~"root"){print $3}}' /etc/passwd 0
!=
[root@localhost ~]# awk -F: '$1!="root"{print $3}' /etc/passwd
1
2
3
4
5
6
7
8
>
[root@localhost ~]# awk -F: '$3>450{print $3}' /etc/passwd
499
[root@localhost ~]# awk -F: '$3>450{print $3,$1,NR}' /etc/passwd
499 saslauth 17
>=
[root@localhost ~]# awk -F: '$3>=450{print $3,$1,NR}' /etc/passwd
499 saslauth 17
<=
[root@localhost ~]# awk -F: '$3<=0{print $3,$1,NR}' /etc/passwd
0 root 1
<
[root@localhost ~]# awk -F: '$3<1{print $3,$1,NR}' /etc/passwd
0 root 1
&&
[root@localhost ~]# awk -F: '$3>5 && $3<50 {print $0,$3}' OFS='\t' /etc/passwd
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown 6
halt:x:7:0:halt:/sbin:/sbin/halt 7
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin 8
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin 10
operator:x:11:0:operator:/root:/sbin/nologin 11
games:x:12:100:games:/usr/games:/sbin/nologin 12
gopher:x:13:30:gopher:/var/gopher:/sbin/nologin 13
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin 14
[root@localhost ~]# awk -F: '{if($1~/root/&&$3<8)print }' /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@localhost ~]# awk -F: '{if($1~/root/&&$3<8){print $0} }' /etc/passwd
root:x:0:0:root:/root:/bin/bash
||
[root@localhost ~]# awk -F: '$3>50 || $1=="root"' /etc/passwd
root:x:0:0:root:/root:/bin/bash
nobody:x:99:99:Nobody:/:/sbin/nologin
vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
saslauth:x:499:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
[root@localhost ~]# awk -F: '{if($3>50 ||$1~/root/){print $0} }' /etc/passwd
root:x:0:0:root:/root:/bin/bash
nobody:x:99:99:Nobody:/:/sbin/nologin
vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
saslauth:x:499:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
数值运算
[root@localhost ~]# awk -F: '$3>100 || $3<5 {print $3}' /etc/passwd
0
1
2
3
4
499
[root@localhost ~]# awk -F: '$3+$4 >100 {print $3"+"$4}' /etc/passwd
12+100
99+99
69+69
499+76
89+89
74+74
[root@localhost ~]# awk -F: '/root|adm/{print $3+10,$3}' OFS="\t" /etc/passwd ##第三个字段加10打印
10 0
13 3
21 11
[root@localhost ~]# awk -F: '/root|adm/{print $3-$4,$3*$4,$3,$4}' OFS="\t" /etc/passwd ##减法,乘法运算。
0 0 0 0
-1 12 3 4
11 0 11 0
[root@localhost ~]# awk '/MemFree/{print $2/1024,int($2/1024)}' /proc/meminfo ##awk的除法和取整运算
365.855 365
if语句
[root@localhost ~]# awk -F: '{if($3>100) print "large"; else print "small"}' /etc/passwd
small
small
small
small
small
small
large
[root@localhost ~]# awk 'BEGIN{ i=0 } { i++ } END{ print i }' /var/log/anaconda.log ##打印行号
267
echo -e "A line 1nA line 2" | awk 'BEGIN{ print "Start" } { print } END{ print "End" }' ##在开始打印start,结尾打印End
Start
A line 1nA line 2
End
双引号拼接使用:
[root@localhost ~]# echo | awk '{ var1="v1"; var2="v2"; var3="v3"; print var1"="var2"="var3; }'
v1=v2=v3
[root@localhost ~]# echo -e "line1 f2 f3\n line2 f4 f5" | awk '{print $NF }'
f3
f5
[root@localhost ~]# echo -e "line1 f2 f3\n line2 f4 f5" | awk '{print $(NF-1) }'
f2
f4
[root@localhost ~]# awk 'END{ print NR }' /etc/passwd #打印行数
19
截取分隔符后的字符串的字符用substr($n,1,8)
awk -F ',' '{print substr($5,1,8)}' file
数组变量拼接
test.txt Table ccccccccccccccccc does not exist COLUMN CELL timestamp=123456789, value=aaaaaaaaaaaaaaaaaaaaaaaaa Table cccccccccccccccccc does not exist COLUMN CELL timestamp=111111111111111111, value=bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb #!/bin/bash cat test.txt |grep 'Table' |awk -F ' ' '{print $2}' >t1.txt cat test.txt |grep 'timestamp' |awk -F '=' '{print $3}' >t2.txt t=`cat test.txt |grep 'Table' |awk -F ' ' '{print $2}'|wc -l` t1=(`cat t1.txt`) t2=(`cat t2.txt`) for((i=0;i<$t;i++)) ; do echo "${t1[$i]},${t2[$i]}" >> t4.txt done
嗨、骚年、快来消灭0回复。