频道栏目
首页 > 资讯 > Sybase > 正文

awk技巧

15-06-02        来源:[db:作者]  
收藏   我要投稿
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表示正在等待处理的请求数;
ESTABLISHED表示正常数据传输状态;
TIME_WAIT表示处理完毕,等待超时结束的请求数。

***********************
7.awk小技巧
***********************

第一行:        NR==1 或 !i++
第n行:        NR==n
最后一行:       0 或 "" 或 1==0 或 1>2 ,总之任一个假值就可以
匹配正则表达式RE的行: /RE/

--7.1取指定行

--7.2从第二行开始打印
awk 'FNR>1 { print $1}' a.txt


awk 'NR==2,NR==0 { print $1}' a.txt


--7.3取中间几行
awk '{if(NR>=302&&NR<=379)$0="#"$0}1' sphinx.conf


--7.4打印每行,并删除第二列
awk '{$2="";print }' test.txt 

--7.5打印部分文本,即输出所有行,但是第一、二列为空

awk '{ $1 = "";$3 = ""; print }' test1          


--7.6打印文件中除第一列和第三列外的其它列、同时从第二行开始打印

awk 'BEGIN{print "ocpyang"}  FNR>1  { $1 = "";$3 = ""; print }' test.txt 


--7.7打印文件中除第一列和第三列外的其它列以及第一行第二行

awk '  NR==1,NR==2  { $1 = "";$3 = ""; print }' test.txt 


--7.8文本间隔:

# 每行后面增加一行空行

awk '1;{print ""}'

awk 'BEGIN{ORS="\n\n"};1'

# 每行后面增加两行空行

awk '1;{print "\n"}'


--7.9每句行前加上编号
awk '{print FNR "\t" $0}' test.txt

其中,0为显示所有列;亦可用1,2来显示1,2列


--7.10用制表符 (\t) 给所有文件加上连贯的编号

awk '{print NR "\t" $0}' test.txt 



---7.11去除#开始的行同时删除空行

awk '!/^#/ && !/^$/ ' wsrep.cnf 

相关TAG标签
上一篇:Ansible(14)wait_for模块
下一篇:联表查询的更新
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站