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表示正在等待处理的请