活在当下
分类: LINUX
2013-09-06 15:47:02
awk 可以处理行或者列
行为记录,用R表示
列为字段,用F表示
0为整行,$0
格式: awk [选项] ‘awk 脚本’ 输入文件
-F fs 使用fs 作为输入记录的字段分隔符
awk 内置变量
NF 当前记录非空字段的编号(当前行有多少个字段)
NR 从所有文件读入的记录号 (当前处理的行数)
示例
1、NR 表示当前处理到哪一行了
[root@localhost dy]# awk -F: '{print NR,$1,$2}' /etc/passwd
1 root x
2 bin x
3 daemon x
4 adm x
5 lp x
6 sync x
7 shutdown x
8 halt x
9 mail x
10 news x
11 uucp x
12 operator x
13 games x
14 gopher x
15 ftp x
16 nobody x
17 mailnull x
18 smmsp x
19 nscd x
20 vcsa x
21 rpc x
22 sshd x
23 rpcuser x
24 nfsnobody x
25 pcap x
26 ntp x
27 dbus x
28 haldaemon x
29 avahi x
30 avahi-autoipd x
31 xfs x
32 gdm x
33 dy x
34 admindy x
[root@localhost dy]#
2、NF 最后一列
[root@localhost dy]# awk -F: '{print NR,$1,$2,$NF}' /etc/passwd
1 root x /bin/bash
2 bin x /sbin/nologin
3 daemon x /sbin/nologin
4 adm x /sbin/nologin
5 lp x /sbin/nologin
6 sync x /bin/sync
7 shutdown x /sbin/shutdown
8 halt x /sbin/halt
9 mail x /sbin/nologin
10 news x
11 uucp x /sbin/nologin
12 operator x /sbin/nologin
13 games x /sbin/nologin
14 gopher x /sbin/nologin
15 ftp x /sbin/nologin
16 nobody x /sbin/nologin
17 mailnull x /sbin/nologin
18 smmsp x /sbin/nologin
19 nscd x /sbin/nologin
20 vcsa x /sbin/nologin
21 rpc x /sbin/nologin
22 sshd x /sbin/nologin
23 rpcuser x /sbin/nologin
24 nfsnobody x /sbin/nologin
25 pcap x /sbin/nologin
26 ntp x /sbin/nologin
27 dbus x /sbin/nologin
28 haldaemon x /sbin/nologin
29 avahi x /sbin/nologin
30 avahi-autoipd x /sbin/nologin
31 xfs x /sbin/nologin
32 gdm x /sbin/nologin
33 dy x /bin/bash
34 admindy x /bin/bash
3、支持的运算(求余,若余数==5则输出行数,以及整行的输出,¥0为整行的输出)
[root@localhost dy]# awk -F: 'NR%10==5{print NR,$0}' /etc/passwd
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
15 ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
25 pcap:x:77:77::/var/arpwatch:/sbin/nologin
[root@localhost dy]#
4、行的处理
[root@localhost dy]# awk -F: 'NR==8,NR==13{print NR,$0}' /etc/passwd
8 halt:x:7:0:halt:/sbin:/sbin/halt
9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10:
11 uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
12 operator:x:11:0:operator:/root:/sbin/nologin
13 games:x:12:100:games:/usr/games:/sbin/nologin
[root@localhost dy]#
5、for循环
[root@localhost dy]# cat dy.txt
aaaaa aaaa
aaaaa aaaa
dd80d dd
dss80d dd
dfdgf dgh
dsfd s
[root@localhost dy]# awk 'NR==1 {for(i=1;i<=NF;i++) {print i, $i}}' dy.txt
1 aaaaa
2 aaaa
6、判断
[root@localhost dy]# awk '{if($4>0&&$4<15){print $0}}'
6、筛选
df -h|awk '/sda8/ {print $2}'
7、显示时用-分隔(通过使用输出字段分隔符 (OFS) 变量,可以在程序中更改此特性。例如,要读取文件(由冒号分隔)并以短划线显示)
awk -F":" '{OFS="-"}{print$1,$2}' /etc/passwd
8、打印行号
FS 和 OFS 是(输入)字段分隔符和输出字段分隔符,它们只是一对可以在 AWK 实用工具中使用的变量。例如,要在打印时为每行编号,可以采用以下方式使用 NR 变量:
awk -F":" '{print NR,$1,$2}' /etc/passwd
9、运算
$ awk '{x=x+($2*$3)} {print $1,"QTY: "$2,"PRICE: "$3,"TOTAL: "$2*$3} END {print "Total Value of Inventory: " x}' inventory
hammers QTY: 5 PRICE: 7.99 TOTAL: 39.95
drills QTY: 2 PRICE: 29.99 TOTAL: 59.98
punches QTY: 7 PRICE: 3.59 TOTAL: 25.13
drifts QTY: 2 PRICE: 4.09 TOTAL: 8.18
bits QTY: 55 PRICE: 1.19 TOTAL: 65.45
saws QTY: 123 PRICE: 14.99 TOTAL: 1843.77
nails QTY: 800 PRICE: .19 TOTAL: 152
screws QTY: 80 PRICE: .29 TOTAL: 23.2
brads QTY: 100 PRICE: .24 TOTAL: 24
Total Value of Inventory: 2241.66
10、重定向
$ awk '{print NR, $1 ) > "/tmp/filez" }' emp_names
11 、awk之相同$1的行去重输出
#文件合并
stra b
stra c
stra d
strb 1
strb 2
strb 3
结果:
stra
b
c
d
strb
1
2
3
awk '{print $1==i?$2:$1"\n"$2;i=$1}' file
[解析]
这是一个典型awk中?:的逻辑判断,类似if else。打印当$1等于i时,打印$2的值,这时候i并没有任何值,条件不成立,然后执行:后面的内容,那就是打印$1换行打印$2,并把$1的值赋给i。这时候就已经打印出了
stra
b
这样的内容。然后又重新执行第2行判断,这时候$1的值是stra,第2行的$1是stra条件成立,那么打印$2
stra
b
c
然后匹配第3行。以此类推。到第4行时,$1是strb,而i的值是stra。条件不成立执行:后的语句把strb赋予i,打印strb换行打印1,这样依次执行,最终得到了结果。在这个范例中,精妙之处就是很好的利用了awk语言中的if else判断。
awk '{print a[$1]?$2:a[$1]=$1RS$2}' file
[解析]
这是一个利用数组下标的运用,首先打印如果符合$1为下标是存在数组a中的那么输出$2,显然这时候数组a还为建立,那么打印冒号后面的内容,把 $1 RS $2 按照$1的下标存入数组,RS是awk内建函数,默认是个换行符,然后打印数组a[$1],这时候内容就是:
stra
b
接着读到第2行,$1为下标是存在与数组a中的那么输出问号后面的内容$2,依次类推内容变成:
stra
b
c
d
命令可以标准写为:awk '{if($1 in a){print $2}else{print a[$1]=$1"\n"$2}}' file
例子:
[root@localhost test]# cat test
stra b
stra c
stra d
strb 1
strb 2
strb 3
[root@localhost test]# cat test.sh
awk '{if($1 in a){a[$1]=a[$1]","$2}else{a[$1]=$2}}END{for(i in a){print i " "a[i]}}' test
[root@localhost test]# sh test.sh
stra b,c,d
strb 1,2,3
[root@localhost test]#