awk一个神奇而又强大的功能,绝对是一个开发利器,效率直选!希望这里的一些总结能帮到那些存在困惑的人!
awk实战1-基础语法说明
awk实战2-流程控制语句总结
awk实战3-awk数组技巧
awk实战4-函数系列-算数函数说明
awk实战5-函数系列-基本字符串函数
awk实战6-函数系列-字符串函数说明-asort和sub
awk实战7-函数系列-时间函数
awk实战8-函数系列-字节操作
awk实战9-IO函数-getline和close
awk实战10-IO函数-其他介绍
awk实战11-进阶-10种awk有效应用实战
awk实战12-进阶-再谈awk匹配模式
awk处理小问题-解决局部jar包替换
上文我们讲了awk的基本语法,可以发现awk是一种基于
模式-动作
的文本处理语言;本文以wc用法开头,主要呈现awk命令的十种常用用法。awk ‘pattern{action}pattern{action}…’ file
cat filename | awk 'BEGIN {print "SUM:"} {w += NF; c += length + 1} END {print "END SUM:", NR, w, c}'
a. cat命令将文件参数打印传入管道;
b.awk命令在BEGIN
动作块中打印:“SUM:”
c.在过程匹配动作中,采用默认匹配,也就是匹配分隔符“空格”,变量w加上当前域个数,也就是分割单词个数,最终得到累计单词个数,变量c机上当前域的长度,得到累计字符个数;
c.END
动作块最终打印输出文件行数、单词总数、字符总长度;
user@user:~/$ yes Hello Wold | awk 'NR % 4 == 1, NR < 8 { printf "%6d %s\n", NR, $0 }' | head -n 10
1 Hello Wold
5 Hello Wold
9 Hello Wold
10 Hello Wold
11 Hello Wold
12 Hello Wold
13 Hello Wold
14 Hello Wold
15 Hello Wold
16 Hello Wold
yes命令重复输入其参数(默认则是输出“y”)。在这里,我们让该命令输出“Hello Wold”。动作块则输出带行号的内容。printf
函数可以模拟标准C中的printf
函数,其效果与前述的print
函数类似。而符合模式的行是这样产生的:NR
是记录的编号,也就是AWK正在处理行的行号(从1开始)。“%”是取余数操作符。因此,NR % 4 == 1
对第1,5,9等行为真。类似的,NR % 4 == 3
对3,7,11等行为真。范围模式在其第一部分匹配(例如对第1行)之前为假,并在第二部分匹配(例如第3行)之前为真。然后,再在第二次匹配上其第一部分(例如第5行)前为假。sed
命令则是用于截取其前7行输出,防止yes
命令一直运行下去。若head
命令可用的话,这行命令的效果和head -n7
相同。 若范围模式的第一部分永远为真,例如设定为“1”,可以用来使该范围从输入的最开始开始。类似的,若第二部分总是为假,例如“0”,则该范围的结束即为输入的结束。
使用print $NF
可以打印出一行中的最后一个字段,使用$(NF-1)
则是打印倒数第二个字段,其他以此类推:
user@user:~/$ echo -e "line1 f2 f3n \n line2 f4 f5" | awk '{print $NF}'
f3n
f5
user@user:~/ echo -e "line1 f2 f3n \n line2 f4 f5" | awk '{print $(NF-1)}'
f2
f4
首先我们了解以下sed完成这个功能的写法
#### sed用法介绍
sed '[行号]c new data' filename
sed '[起始行号],[终止行号]c new data' filename
#### 加入-i直接修改文件
sed -i '2c new test!' a.log
#### 修改最后一行
sed -i '$c new test111!' a.log
#### 修改第一行
sed -i '1c new test111!' a.log
使用awk写法如下:
awk 'NR==[行号] {print "指定内容"} 1' filename > filename_new
NR为处理当前行号显示:
cat $1 | awk -v min=$2 -v max=$3 'NR>=min && NR<=max'
如下图所示为一个用例:
cat test | awk 'NR>10 && NR <= 30'
实用正则表达式/^$/代表空行条目;
user@user:~$ awk '/^$/{i=i+1}END{print i}' /etc/hosts
1
关键描述:
- 实用正则表达式[/]+代表斜杠,分割得到中间部分
- 使用uniq来识别同名项目,并统计个数
如下所示为准备数据test.log
http://www.etiantian.org/index.html
http://www.etiantian.org/1.html
http://post.etiantian.org/index.html
http://mp3.etiantian.org/index.html
http://www.etiantian.org/3.html
http://post.etiantian.org/2.html
使用命令如下所示:
user@user:~$ cat test | awk -F '[/]+' '{print $2}' | uniq -c
2 www.etiantian.org
1 post.etiantian.org
1 mp3.etiantian.org
1 www.etiantian.org
1 post.etiantian.org
将倒数第三列的内容作为字符串索引存入了数组fa,注意这里利用了awk数组的特性!
方法一:
awk '/Failed/{fa[$(NF-3)]++}END{for(pol in fa)print pol,fa[pol]}' secure-20161219|column -t
方法二:
awk '/Failed/{print $(NF-3)}' secure-20161219 |sort|uniq -c|sort -n
实用awk模块通过指定行跳过或者匹配,将重要内容进行呈现,可以极大简化我们定位问题的速度;
##### 1-剔除指定模块日志
sudo awk '/gdm-x-session/{next}/fcitx-ui-sogou-qimpanel.desktop/{next}1' syslog
##### 2-仅显示包含error的日志
sudo awk '/error/{print}' syslog
此处通过
/^ \t/+/
匹配了行前的空格行;这个用例特别适用于平时我们提交信息的比如git-commit信息的一些语法检测,有非常重要的作用!
user@user:~$ cat test
http://www.etiantian.org/index.html
http://www.etiantian.org/1.html
http://post.etiantian.org/index.html
http://mp3.etiantian.org/index.html
http://www.etiantian.org/3.html
http://post.etiantian.org/2.html
asdfasdfsd
adfsdf
---------------------------------
user@user:~$ awk '/^[ \t]+/{print NR"--->"$1}' test
1--->http://www.etiantian.org/index.html
2--->http://www.etiantian.org/1.html
3--->http://post.etiantian.org/index.html
4--->http://mp3.etiantian.org/index.html
5--->http://www.etiantian.org/3.html
6--->http://post.etiantian.org/2.html
8--->adfsdf
user@user:~$ gawk '/^[ \t]+/{print NR"--->"$1}' test | wc -l
7