shell文本处理工具awk

3年前 (2017-08-14) gtj linux, shell 0评论 已收录 182℃

awk是一个强大的文本分析工具,运行效率高,而且代码简单,对格式化的文本处理能力超强。awk有3个不同版本: awk、nawk和gawk,未作特别说明,一般指gawk,gawk是AWK的GNU版本。
语法:

awk命令形式:

awk [-F|-f|-v] 'BEGIN{} //{command1; command2} END{}' file
[-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回复。

×
订阅图标按钮
Less is more!!!