因为最近的工做内容的关系, 常常须要对文本文件作一些处理. 每次都要写个脚原本处理实在是有点麻烦. 这时候想起来好久之前稍微接触过的AWK, 来作这个工做真的是再合适不过了.python
所以, 趁着这个机会, 把AWK深刻学习一点,记录在此.linux
AWK是一门解释型的编程语言。在文本处理领域它是很是强大的,它的名字来源于它的三位做者的姓氏:Alfred Aho, Peter Weinberger 和 Brian Kernighan。正则表达式
GNU/Linux发布的AWK目前由自由软件基金会(FSF)进行开发和维护,一般也称它为 GNU AWK。shell
awk在下列任务中都有很是不错的发挥, 本文后续也会举不少示例.编程
简单来讲awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各类分析处理。微信
你能够将其理解为一个linux命令,只是使用参数以及方法多样一些. 由于咱们常常会在命令行直接使用它.编程语言
你也能够将其理解为一个简易的脚本语言, 由于在使用过程当中咱们也能够写逻辑表达式等各类语句.函数
先来个热场的示例.学习
已有一个文本文件,格式以下:url
前面的数字是热度, 后面的字符串是搜索词.
100 阿里巴巴
200 京东
300 淘宝
400 awk怎么使用
复制代码
咱们想计算, 热度大于等300的词的热度, 在总热度中的一个比例
虽然听起来有点绕, 可是这是一个很是常见的需求, 对应到这个示例中咱们是想计算 (300 + 400 ) / ( 100 + 200 + 300 + 400), 此时咱们只能打开咱们的编译器, 选择一门语言以后开始写代码了. 其实不用.
把上面的文本内容放进 a.txt中,而后执行下面的shell命令便可, 你会看到预期之中的 0.7.
awk '{{if ($1 >= 300) {sub_sum +=$1}};sum += $1 }; END{ret = sub_sum * 1.0 / sum; print ret}' a.txt
复制代码
这段脚本作了什么事情呢?
怎么样, 是否是比写其余shell或者python脚本快多了?
接下来将进入学习时间, 咱们逐个知识点的学习,看完本文,你也能这么花里胡哨的解决文本处理问题~.
awk除了能够在命令行执行以外, 还能够写成脚本文件进行执行.咱们大体的了解一下这个用法,以后不作详细讲解,以命令行用法为主要内容. 由于文本的用户和命令行大同小异.
首先,建立一个包含脚本内容的文本文件 test.awk
{print $1 }
复制代码
而后咱们用命令行执行这个脚本文件.
awk -f command.awk marks.txt
复制代码
这个实际上是至关于命令行直接执行的一个扩展, 当你写的脚本十分复杂(不推荐),且须要多人合做或者共享的时候, 脚本文件会是一个不错的选择.
awk [options] file ...
复制代码
把上面脚本文件语法中的内容写到 options 便可.
上面所讲的, 是 awk是什么以及 怎么在系统中使用awk,接下来的内容就是 awk自身的一些语法.
awk程序的思路是, 逐行处理一个文件.
那么让咱们想一下, 当咱们想要 处理一个文件的时候会须要作些什么?
awk的程序结构也是如此.
BEGIN 语句块
BEGIN {awk-commands}
复制代码
BEGIN语句块在程序开始的使用执行,它只执行一次,在这里能够初始化变量。BEGIN是AWK的关键字,所以它必须为大写,注意,这个语句块是可选的。
BODY 语句块
/pattern/ {awk-commands}
复制代码
BODY语句块中的命令会对输入的每一行执行,咱们也能够经过提供模式来控制这种行为。注意,BODY语句块没有关键字。
END 语句块
END {awk-commands}
复制代码
END语句块在程序的最后执行,END是AWK的关键字,所以必须为大写,它也是可选的。
因此一个添加了所有可选项的awk命令以下所示:
awk [options] 'BEGIN{};{};END{}' file.txt
复制代码
awk对经常使用的操做符都有支持,且与c语言使用方法同样.具体支持的操做符有:
awk支持流程控制, 好比在本文最前方的示例中咱们使用了if语句.
或者相似下面的if语句都是合法的.
awk 'BEGIN {
a = 30;
if (a==10)
print "a = 10";
else if (a == 20)
print "a = 20";
else if (a == 30)
print "a = 30";
}'
复制代码
循环操做与其余C系语言同样,主要包括 for,whlie,do...while,break,continue 语句.
示例:
awk 'BEGIN {
sum = 0; for (i = 0; i < 20; ++i) {
sum += i; if (sum > 50) exit(10); else print "Sum =", sum
}
}
复制代码
与内建变量相对应的, 也有一部分的内建函数.
awk 还提供了一些内置函数,好比:
内建函数还有一些其余的, 具体能够在使用时在 man awk
中查询.
虽然我我的是不支持用awk来作这么繁杂的编程工做的,可是awk支持咱们自定义函数而且调用. 语法规范以下:
function function_name(argument1, argument2, ...) {
function body
}
复制代码
咱们能够在一个awk脚本中放入一下内容, 而后执行它.
function main(){
print "function"
}
BEGIN {
main()
}
复制代码
这里会列出一些经常使用的,简单的使用示例.
全部的示例都如下面的示例为输入进行运行.
1) Amit Physics 80
2) Rahul Maths 90
3) Shyam Biology 87
4) Kedar English 85
5) Hari History 89
复制代码
打印某列或者字段
AWK能够只打印输入字段中的某些列。
$ awk '{print $3 "\t" $4}' marks.txt
Physics 80
Maths 90
Biology 87
English 85
History 89
复制代码
在示例文本中,第三列包含了科目名,第四列则是得分,上面的例子中,咱们只打印出了这两列,$3 和 $4 表明了输入记录中的第三和第四个字段。
打印全部的行
默认状况下,AWK会打印出全部匹配模式的行
$ awk '/a/ {print $0}' marks.txt
2) Rahul Maths 90
3) Shyam Biology 87
4) Kedar English 85
5) Hari History 89
复制代码
上述命令会判断每一行中是否包含a,若是包含则打印该行,若是BODY部分缺失则默认会执行打印,所以,上述命令和下面这个是等价的
$ awk '/a/' marks.txt
复制代码
打印匹配模式的列
当模式匹配成功时,默认状况下AWK会打印该行,可是也可让它只打印指定的字段。例如,下面的例子中,只会打印出匹配模式的第三和第四个字段。
$ awk '/a/ {print $3 "\t" $4}' marks.txt
Maths 90
Biology 87
English 85
History 89
复制代码
任意顺序打印列
$ awk '/a/ {print $4 "\t" $3}' marks.txt
90 Maths
87 Biology
85 English
89 History
复制代码
统计匹配模式的行数
$ awk '/a/{++cnt} END {print "Count = ", cnt}' marks.txt
Count = 4
复制代码
打印超过18个字符的行
$ awk 'length($0) > 18' marks.txt
3) Shyam Biology 87
4) Kedar English 85
复制代码
查找history历史中,最经常使用的10个命令
history | awk '{a[$2]++}END{for(i in a){print a[i] " " i}}' | sort -rn | head
复制代码
过滤文件中重复行
awk '!x[$0]++' <file>
复制代码
将一行长度超过 72 字符的行打印
awk 'length>72' file
复制代码
查看最近哪些用户使用系统
last | grep -v "^$" | awk '{ print $1 }' | sort -nr | uniq -c
复制代码
计算文本中的数值的和
awk '{s+=$1} ENG {printf "%.0f", s}' /path/to/file
复制代码
当你用的时候临时有忘记的或者不肯定的,随时能够查看帮助命令.
man awk
复制代码
完。
以上皆为我的所思所得,若有错误欢迎评论区指正。
欢迎转载,烦请署名并保留原文连接。
联系邮箱:huyanshi2580@gmail.com
更多学习笔记见我的博客或关注微信公众号 <呼延十 >------>呼延十