awk技巧(一)

2015-07-24 08:37:55 · 作者: · 浏览: 0
awk默认就是空格和TAB,如果要指定用TAB可以用
awk -F '\t'
如果要指定多个TAB当作一个处理,可以用
awk -F '\t+' 


***********************
1.基本完整用法
***********************


---1.基本完整用法

last -n 5 |awk '!/^$/' | awk 'BEGIN {print "username,IP" } {print $1,$3} \
END {print "最后登录的用户和ip地址"}'


---2.查看最后登录的五个用户和ip地址并去掉空行

last -n 5 |awk '!/^$/' | awk 'BEGIN {print "username,IP" } {print $1,$3} \
END {print "最后登录的用户和ip地址"}'

--首选
last -n 5 |awk 'BEGIN {print "username,IP" } !/^$/ {print $1,$3} \
END {print "最后登录的用户和ip地址"}'



***********************
----2.AWK循环
***********************
---2.1 显示所有用户名
awk -F ':' 'BEGIN {count=0;} {name[count] = $1;count++;}; \
END{for (i = 0; i < NR; i++) print i, name[i]}' /etc/passwd

---2.2循环显示目录名

find  /etc/sysconfig/network-scripts/ -name "ifcfg-*"  |awk -F "/" ' {print $5}'  >test.txt


cat test.txt

ifcfg-em1
ifcfg-em2
ifcfg-lo
ifcfg-em1
ifcfg-em2
ifcfg-lo
ifcfg-em1
ifcfg-em2
ifcfg-lo
ifcfg-08
ifcfg-10
ifcfg-l1

--#带行号显示(数组)

awk  'BEGIN {count=0;} {name[count] = $1;count++;}; \
END{for (i = 0; i < NR; i++) print i, name[i]}' /root/test.txt


---结果为:
0 ifcfg-em1
1 ifcfg-em2
2 ifcfg-lo
3 ifcfg-em1
4 ifcfg-em2
5 ifcfg-lo
6 ifcfg-em1
7 ifcfg-em2
8 ifcfg-lo
9 ifcfg-08
10 ifcfg-10
11 ifcfg-l1



--#不带行号显示

# awk '{for(i=1;i<=NF;i++) {printf $i" "} printf "\n"}'   /root/test.txt

ifcfg-em1 
ifcfg-em2 
ifcfg-lo 
ifcfg-em1 
ifcfg-em2 
ifcfg-lo 
ifcfg-em1 
ifcfg-em2 
ifcfg-lo 
ifcfg-08 
ifcfg-10 
ifcfg-l1 



df -H |awk -F '\t' '{ print $1,$2,$3,$4,$5,$6}'



***********************
3.awk模糊
***********************
--3.1模糊匹配:

             查询第四列中是否含有Brown

             $awk  '{if($4~/Brown/) print $0}'   grade.txt

             如果在文本中查询字符串"Brown",使用/Brown/

                 和

             $awk   '$4~/Brown/'  grade.txt                 

             作用相同。

--3.2模糊不匹配
            $ awk '$0 !~ /Brown/' grade.txt
            $ awk '{if($4 !~ /Brown/) print $0' grade.txt



--3.3匹配字符或字符串

# awk -F: '$1~/me/' passwd 
games:x:12:100:games:/usr/games:/sbin/nologin

# awk -F: '$1~/user/' passwd 
user1:x:600:501::/home/user1:/bin/bash
可以让某个段去匹配,~ 表示匹配的意思,以冒号分隔第一字段然后匹配//里的关键字;
1
2
3
4
5
6

# awk -F: '/root/ {print $1,$3} /user/ {print $1,$3}' passwd 
root 0
operator 11
ftp 14
saslauth 499
user1 600
awk还可以多次匹配


***********************
4.精确匹配
***********************

$ awk '$3 == "48" {print $0}' grade.txt

$ awk '{if ($3=="48") print $0}' grade.txt


# awk -F: '$3=="0"' passwd 
root:x:0:0:root:/root:/bin/bash

# awk -F: '$3==10' passwd 
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin

判断第3个字段为10的并且打印该行的第7字段;
1
2
3
4

# awk -F: '$3==10 {print $7}' passwd 
/sbin/nologin
# awk -F: '$3=="600"' passwd 
user1:x:600:501::/home/user1:/bin/bash

awk中是可以用逻辑符号判断的,比如 ‘==’ 就是等于,也可以理解为 ‘精确匹配’ 另外也有 >, ‘>=, ‘<, ‘<=, ‘!= 等等,值得注意的是,在和数字比较时,若把比较的数字用双引号引起来后,那么awk不会认为是数字,而认为是字符,不加双引号则认为是数字。

示例,双引号括起来认为是字符;加单引号和不加则认为是数字;

# awk -F: '$3>
"500"' passwd | sort -t: -k 3 -n shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin sshd:x:74:74:privilege-separated ssh:/var/empty/sshd:/sbin/nologin dbus:x:81:81:system message bus:/:/sbin/nologin postfix:x:89:89::/var/spool/postfix:/sbin/nologin nobody:x:99:99:nobody:/:/sbin/nologin user1:x:600:501::/home/user1:/bin/bash # awk -F: '$3>500' passwd | sort -t: -k 3 -n user1:x:600:501::/home/user1:/bin/bash # awk -F: '$3>'500'' passwd | sort -t: -k 3 -n user1:x:600:501::/home/user1:/bin/bash *********************** 5.精确不匹配 *********************** $awk '$4!="brwon" {print $0}' grade.txt # awk -F: '$7!="/sbin/nologin"' passwd root:x:0:0:root:/root:/bin/bash sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt user1:x:600:501::/home/user1:/bin/bash mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/bash # awk -F: '$3>"5" && $3<"7"' passwd shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin user1:x:600:501::/home/user1:/bin/bash 另外还可以使用 && “并且”和 || “或者” 的意思。 示例,打印第3段大于第4段,并且第7段为/bin/bash的行; # awk -F: '$3>$4 && $7=="/bin/bash"' passwd user1:x:600:501::/home/user1:/bin/bash NOTE:尖角符号代表行首,“.”代表任意字符。 *********************** 6.统计功能 *********************** netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' NOTE: ^ 是开头的意思,就是说开头是TCP字样的,$NF表示最后一个字段,把它放入数组S中,然后自加. END最后用for取出数组中的下标,也就是TCP的几种状态,然后对应该下标的值,就是统计的数量. 理解如下: 观察一、先输出两个值,其中NF为awk正在处理记录(行)的字段总数,$NF为每行最后一个字段的值 # netstat -na |awk '/^tcp/ {print NF,$NF}' 6 LISTEN 6 LISTEN 6 LISTEN 6 LISTEN 6 LISTEN 6 LISTEN 6 LISTEN 6 LISTEN 6 LISTEN 6 LISTEN 6 TIME_WAIT 6 TIME_WAIT 6 TIME_WAIT 6 TIME_WAIT 6 ESTABLISHED 6 ESTABLISHED 6 ESTABLISHED 6 ESTABLISHED 6 ESTABLISHED 6 TIME_WAIT 6 TIME_WAIT 6 LISTEN 6 LISTEN 6 ESTABLISHED 观察二、如下命令输出4个值,注意前后俩字段的值是怎么来的。。。S[LISTEN], ++S[LISTEN] # netstat -na |awk '/^tcp/ {print NF,$NF,S[$NF],++S[$NF]}' 6 LISTEN 1 6 LISTEN 1 2 6 LISTEN 2 3 6 LISTEN 3 4 6 LISTEN 4 5 6 LISTEN 5 6 6 LISTEN 6 7 6 LISTEN 7 8 6 LISTEN 8 9 6 LISTEN 9 10 6 TIME_WAIT 1 6 ESTABLISHED 1 6 TIME_WAIT 1 2 6 TIME_WAIT 2 3 6 TIME_WAIT 3 4 6 ESTABLISHED 1 2 6 ESTABLISHED 2 3 6 ESTABLISHED 3 4 6 ESTABLISHED 4 5 6 LISTEN 10 11 6 LISTEN 11 12 6 ESTABLISHED 5 6 观察三、利用awk的行处理特性,遍历了所有tcp开头的行。 定义出不同状态命名的数组下标,并分别++计数赋值给数组元素, 最后打印$NF和数组S[$NF]的值。观察粗体部分 # netstat -na | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' TIME_WAIT 4 ESTABLISHED 6 LISTEN 12 SYN_RECV表示正在等待处理的请