=Start=
0.awk的程序设计模型
awk程序是由所谓的主输入(main input)循环组成的。一个循环是一个例程,它将一直重复执行直到由一些存在的条件终止它。你不必写这个循环,它是现成的,它作为一个框架存在,在这个框架中你编写的代码能够执行。
awk允许你编写两个特殊的例程,它们在任何输入被读取前和所有输入都被读取后执行。它们是与BEGIN和END规则相关的过程。
1.awk的split/substr/index函数的使用
# 使用split返回字符串数组元素个数。 awk 'BEGIN {print split("123#456#678", myarray, "#")}' # 3 netstat -lntp | awk 'NR>2 {a_len=split($4,a,":"); print a_len, a[a_len]}' netstat -lntp | awk 'NR>2 {a_len=split($4,a,":"); print $4, a[a_len]}' netstat -lntp | awk 'NR>2 {b_len=split($NF,b,"/"); print b_len, b[b_len]}' netstat -lntp | awk 'NR>2 {b_len=split($NF,b,"/"); print $NF, b[b_len]}' /sbin/ip a l | grep "inet " | grep -v '127.0.0' | awk '{print $2}' /sbin/ip a l | grep 'inet ' | grep -v '127.0.0' | awk '{print $2}' | xargs | tr ' ' '|' /sbin/ifconfig | grep "inet " | grep -v '127.0.0' | awk '{split($2, a, ":"); print a[2]}' /sbin/ifconfig | grep 'inet ' | grep -v '127.0.0' | awk '{split($2, a, ":"); print a[2]}' | xargs | tr ' ' '|' # awk的 split 函数无法指定切分的次数,所以在碰到下面的那种启动进程的方式时就容易有问题 # # netstat -lntp # Active Internet connections (only servers) # Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name # tcp 0 0 0.0.0.0:7710 0.0.0.0:* LISTEN 1270/./redis-3.0.0/ # tcp 0 0 0.0.0.0:7712 0.0.0.0:* LISTEN 1271/./redis-2.8.23 ## 使用 index 和 substr 达到类似的功能 ## # netstat -lntp | awk 'NR>2 {pos=index($NF, "/"); print $NF, pos}' 1309/mysqld 5 10790/./redis-3.0.5 6 1195/sshd 5 1380/master 5 10790/./redis-3.0.5 6 1195/sshd 5 # netstat -lntp | awk 'NR>2 {pos=index($NF, "/"); print substr($NF, pos)}' /mysqld /./redis-3.0.5 /sshd /master /./redis-3.0.5 /sshd # netstat -lntp | awk 'NR>2 {pos=index($NF, "/"); print substr($NF, pos+1)}' #可以直接使用'+'进行算术操作 mysqld ./redis-3.0.5 sshd master ./redis-3.0.5 sshd
2.awk的next的使用
#示例:解析XML文件(过滤掉空行和注释行) $ cat "$file" | awk '/<!--/,/-->/{next}1' | tr -d '\n\r' | sed 's/>/>\n/g' | tr '\t' ' ' | tr -s ' ' | sed 's/^ //g;s/ $//g' | grep -v '^$'
3.用awk处理多行记录
#为了处理以下这种包含多行数据的记录,我们可以将字段分隔符(FS)定义为换行符,并将记录分隔符(RS)设置为空字符串——它代表一个空行。 $ cat ./multi_line_record.txt John Daggett Koren Inc. 341 King Road Plymouth MA 01760 696-0987 Alice Ford Meituan Inc. 22 East Broadway Richmond VA 08239 699-1998 $ awk 'BEGIN{ FS = "\n"; RS = "" } { print $1, $NF }' multi_line_record.txt John Daggett 696-0987 Alice Ford 699-1998
注意:
在命令行中使用awk时,必须有:
- 单引号
- 大括号
参考链接:
- http://www.linuxsong.org/2010/09/awk-string-function/
- http://stackoverflow.com/questions/8009664/split-string-to-array-using-awk
=EOF=
《 “Awk学习_6” 》 有 6 条评论
linux awk 内置函数详细介绍(实例)
http://www.cnblogs.com/chengmo/archive/2010/10/08/1845913.html
“`
##awk复杂分隔符##
多字符作分隔符
$ echo “a||b||c||d” | awk -F ‘[|][|]’ ‘{print $3}’
c
多种分隔符1
$echo “a||b,#c d” | awk -F ‘[| ,#]+’ ‘{print $4}’
d
多种分隔符2
$echo “a||b##c|#d” | awk -F ‘([|][|])|([#][#])’ ‘{print $NF}’
c|#d
“`
awk中的FieldSeparator可以是由多字符组成的,比如:
“`
$ echo ‘”School”,”College”,”City”‘ | awk -F’”,”|^”|”$’ ‘{for(i=1;i<=NF;i++){if($i)print $i}}'
School
College
City
“`
如果你希望awk按普通字符解释「管道字符——'|'」,你需要用下面的方法:
“`
$ echo "a|b|c|d" | awk -F '[|]' '{print $3}'
“`
awk拆分文件很简单,使用重定向就好了。下面这个例子,是按第6例分隔文件,相当的简单(其中的NR!=1表示不处理表头)。
`
$ cat netstat.txt
Proto Recv-Q Send-Q Local-Address Foreign-Address State
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN
tcp 0 0 coolshell.cn:80 124.205.5.146:18245 TIME_WAIT
tcp 0 0 coolshell.cn:80 61.140.101.185:37538 FIN_WAIT2
tcp 0 0 coolshell.cn:80 110.194.134.189:1032 ESTABLISHED
$ awk ‘NR!=1{print > $6}’ netstat.txt
$ ls
ESTABLISHED FIN_WAIT2 LISTEN netstat.txt TIME_WAIT
`
你也可以把指定的列输出到文件:
`$ awk ‘NR!=1{print $4,$5 > $6}’ netstat.txt
`
再复杂一点:(注意其中的if-else-if语句,可见awk其实是个脚本解释器)
`
$ awk ‘NR!=1{if($6 ~ /TIME|ESTABLISHED/) print > “1.txt”;
else if($6 ~ /LISTEN/) print > “2.txt”;
else print > “3.txt” }’ netstat.txt
`
AWK 简明教程
http://coolshell.cn/articles/9070.html
Linux之awk内建数学函数之左移运算、右移运算、按位取反运算
https://www.dwhd.org/20150917_013542.html
Linux之awk中 !a[$0]++ 与 !a[$1…]++ [转载自苦海无边博客]
https://www.dwhd.org/20150917_020937.html
Linux之awk实现ip地址转二进制和数字模式&十进制转二进制
http://www.dwhd.org/20150910_011543.html
Linux之awk实现ls -l输出文件权限的数字&打造加强版的ls命令
http://www.dwhd.org/20150909_020139.html
当使用awk的多分隔符进行字符串切分的时候,要注意下面这种使用方式需要对【.】进行转义才行
`
cat enterprise-ssid.txt| sort | uniq | awk -F’ |-|_|\\.’ ‘NF>1 {print tolower($2)}’ | sort | uniq -c | sort -rn
`