文本处理神器Awk语言详解
文章目录
- 初步认识
- 命令执行
- 脚本文件
- 输入输出
- 管道
- 基本语法
- 运算符
- 流程控制
- 函数封装
- 内置变量
- 内置函数
- 算术和位操作函数
- 字符串函数与正则表达式
- 字符输出函数
- 时间函数
- 其它函数
初步认识
AWK主要用于文本数据处理,由Afred, Weinberger和Kernighan设计,故名AWK。
AWK的初始版本由AT&T实验室开发,此外,NAWK
是AWK的改进版本,而应用最广泛的当属GAWK
,即GNU AWK
,为Linux内置的默认版本,对AWK和NAWK可以完全兼容。
Awk
的程序结构包括三个区块:
- 开始块
BEGIN {awk-commands}
- 主体块
/pattern/ {awk-commands}
- 结束块
END {awk-commands}
其中awk-commands
表示awk
指令;/pattern/
表示指定的处理模式。
以文本文件test.txt
为例,下面为其内容
1) Amit Physics 80
2) Rahul Maths 90
3) Shyam Biology 87
命令执行
通过awk
可以逐行打印出这个文本文件,并可以添加表头,方法如下
$ awk 'BEGIN{printf "No\tName\tSub\tMarks\n"}{print}' test.txt
No Name Sub Marks
1) Amit Physics 80
2) Rahul Maths 90
3) Shyam Biology 87
其基本方法为,可用awk
直接调用后面的字符串中所写的脚本命令。其中BEGIN
标识的大括号为开始块,用于打印表头;后面的{print}
为主体块,表示按行打印test.txt
中的内容。
通过$
选列,可实现单行输出,例如只想输出人名,则
awk 'BEGIN{printf "Name\n"}{print $2}' test.txt
Name
Amit
Rahul
Shyam
其中$2
表示第二列。
脚本文件
通过awk -f
命令,可以执行脚本,例如可将同样的功能封装入脚本test.awk
中,
# test.awk文件
BEGIN{printf "Name\n"
}
{print $2
}
然后在命令行中调用,其效果与刚刚相同
$ awk -f test.awk test.txt
Name
Amit
Rahul
Shyam
输入输出
除了可以将处理结果打印在命令行中,awk
也可以将其输出到文本文件,其方法为
print DATA > oFile
print DATA >> oFile
可将DATA
输出到oFile
中,如果oFile
不存在,则先创建该文件。>
为写入模式,若oFile
存在,数据输出前会将oFile
中原有的数据删除;>>
为追加模式,数据将在oFile
结尾写入。
下例将test.txt
打开,并重新存储到new.txt
中
awk '{ print $0 > "./new.txt" }' test.txt
当然也可以交换两列的位置
$ awk '{print $4,$3,$2,$1 > "./new.txt"}' test.txt
$ cat new.txt
80 Physics Amit 1)
90 Maths Rahul 2)
87 Biology Shyam 3)
管道
AWK
可通过管道将一个程序的输出传递给另一个程序,其使用方法为
print items | command
例如下例将hello, world"
传递给tr
。
$ awk 'BEGIN { print "hello, world" | "tr [a-z] [A-Z]" }'
HELLO, WORLD !!!
通过|&
可使用双工管道,进行双向通信
# 文件pipe.awk
BEGIN {cmd = "tr [a-z] [A-Z]" # 建立双向通信惯导print "hello, world !!!" |& cmd # 为tr提供输入close(cmd, "to") # 执行后关闭to进程cmd |& getline out # 将输出存储到out中print out; # 打印outclose(cmd); # 关闭cmd
}
执行脚本后可得到
HELLO, WORLD !!!
基本语法
运算符
+, -, *, \, %, ^, **
|
加减乘除、取模、乘方、乘方 |
+=, -=, *=, \=, %=, ^=
|
加减乘除、取模、乘方对应的复制符 |
++a, --a, a++, a--
|
前置递增、前置递减、后置递增、后置递减 |
==, !=, <, <=, >, >=
|
关系运算符,返回真假 |
`&&, |
awk
也支持三元运算符,例如
$ awk 'BEGIN { a = 10; b = 20; (a > b) ? max = a : max = b; print "Max =", max}'
Max = 20
除了单个值的计算,awk
还提供了适用于其他数据类型的运算符
- 字符串连接:
空格
- 数组遍历:
in
- 匹配:
~
;不匹配!~
数组遍历的方法为:
BEGIN {arr[0] = 1; arr[1] = 2; arr[2] = 3; for (i in arr) printf "arr[%d] = %d\t", i, arr[i] print "\n"
}
调用结果为:
awk -f test.awk
arr[0] = 1 arr[1] = 2 arr[2] = 3
流程控制
编程语言的流程控制,主要包括判断和循环。
其判断语句就是if...else if...else
的结构:
$ awk 'BEGIN{num=10; if(num%2==0){printf "%d is even\n", num }else{printf "%d is odd"}}'
10 is even
循环在前面的例子也出现过,包括for
循环、while
循环以及do{}while()
,其逻辑与C语言极度相似,故只列一例不做详述。
$ awk 'BEGIN { for (i = 1; i <= 5; ++i) printf "%d\t",i }'
1 2 3 4 5
$ awk 'BEGIN{ i=1; while(i<5){printf "%d\t", i; i++}}'
1 2 3 4
$ awk 'BEGIN{ i=1; do{printf "%d\t", i++}while(i<5)}'
1 2 3 4
在循环中可以通过break
和continue
来结束或跳过本层循环,这也同样与C语言雷同。此外,awk
还有一个关键字exit
,类似于return 0
,可以跳出当前程序。
函数封装
在awk
中封装函数用关键字function
,例如
# 文件 fcunTest.awk
function fac(n){if(n>1)return n*fac(n-1)elsereturn 1
}
BEGIN{printf "5+1=%d", fac(5)
}
这是个递归求阶乘的函数,调用结果为
$ awk -f funcTest.awk
fac(5)= 120
内置变量
AWK 提供了一些内置变量,列表如下
变量 | 说明 | 默认值 |
---|---|---|
ARGC
|
表示在命令行提供的参数的个数 | |
ARGV
|
命令行输入的参数数组 | 索引从0开始 |
CONVFMT
|
数据转换为字符串的格式 | %.6g |
OFMT
|
数值输出格式 | %.6g |
ENVIRON
|
环境变量数组 | |
FILENAME *
|
当前文件名称 | |
FS
|
输入列之间的分隔符 | 空格 |
NF
|
当前输入记录中域的数量 | |
NR
|
当前记录的数量 | |
FNR
|
当前文件的NR | |
OFS
|
输出列之间的分割符 | 空格 |
ORS
|
行间分割符 | 换行符 |
RLENGTH
|
match 匹配字符串长度
|
|
RS
|
输入行的分割符 | 换行符 |
RSTART
|
match匹配字符串的首字符的位置 | |
SUBSEP
|
数组下标的分割行符 | \03 |
$0
|
整个输入记录 | |
$n
|
当前输入的第n列 |
* 表示开始块中未定义
以ARGV
和ARGC
为例,可演示一下如何查看这些默认变量
awk 'BEGIN { for (i = 0; i < ARGC - 1; ++i){ printf "ARGV[%d] = %s\t", i, ARGV[i] } }' a b c d
ARGV[0] = awk ARGV[1] = a ARGV[2] = b ARGV[3] = c
此外,GNU AWK
还提供了其他几个内置变量
ARGIND
|
正在处理的ARGV索引 |
ERRNO
|
失败信息 |
FIELDWIDTHS
|
列宽 |
IGNORECASE
|
设置后大小写不敏感 |
TEXTDOMAIN
|
AWK程序当前文本域 |
BINMODE
:即二进制模式,用于非 POSIX 系统。 数值1、2、3分别指定输入文件、输出文件或所有文件;字符串r
或w
分别指定输入或输出文件使用二进制模式;rw
或wr
指定所有文件使用二进制模式。LINT
:提供了在GAWK
程序中动态控制--lint
选项的一种途径。此变量设置后,GAWK会输出lint
警告信息。如果给此变量赋予字符值fatal
,lint 的所有警告信息将会变了致命错误信息(fatal errors)输出,和–lint=fatal 效果一样。
内置函数
算术和位操作函数
and, or, compl, xor
|
按位求与、或、非、异或 |
lshift, rshift
|
左移位、右移位 |
cos(x), sin(x)
|
cos x , sin x \cos x, \sin x cosx,sinx |
exp(x), log(x), sqrt(x)
|
exp x , ln x , x \exp x, \ln x, \sqrt x expx,lnx,x |
atan2(y,x)
|
arctan y x \arctan\frac{y}{x} arctanxy |
int(x)
|
取整 |
rand(), srand(n)
|
返回区间 ( 0 , 1 ) (0,1) (0,1)的一个随机数 后者根据随机数种子n来生成 |
字符串函数与正则表达式
基础功能 | ||
---|---|---|
asort(arr,[, d [,how] ])
|
对数组arr的值进行字符排序 | |
asorti(arr,[, d [,how] ])
|
对数组arr的索引进行字符排序 | |
gsub(a, b [, tar])
|
将tar 中的子串a 替换为b ,tar 默认$0
|
|
index(str,sub)
|
返回sub 在str 的位置;若不存在则返回0
|
|
length(str)
|
返回字符串长度 | |
strtonum(str)
|
将str 转为数值 [ 1 ] ^{[1]} [1]
|
|
tolower(str)
|
将str 转换为小写格式然后返回 [ 1 ] ^{[1]} [1]
|
|
toupper(str)
|
将str 转换为大写格式然后返回 [ 1 ] ^{[1]} [1]
|
|
substr(str, st, L)
|
返回str 中从第st 个字符开始长度为L 的子串
|
- [1] strtonum的输入字符串,如以
0
开始,则转为八进制数;如以0x
或0X
开始,则当作十六进制数;否则当作浮点数。 - [2]
tolower
和toupper
并不会改变输入字符串str
本身。
与正则表达式相关的功能 | |
---|---|
match(str, regex)
|
返回在str 中与regex 匹配的子串的位。
|
sub(regex,sub,str)
|
将str 首次出现的与regex 匹配的子串替换为sub str 默认为$0
|
split(str, arr,regex)
|
使用regex 分割str ,输出给arr
|
其中regex
均表示正则表达式;match
返回的字符串为匹配的最长、最左侧的字符串,如果匹配失败,返回0。
所谓正则表达式,就是通过匹配符来替代特定文字的方法,其常用的匹配字符如下
匹配字符 | |
---|---|
.
|
除了行结束字符的所有字符 |
^
|
匹配一行的开始 |
$
|
匹配一行的结束 |
[]
|
匹配方括号中的任意字符 |
[^]
|
匹配除了[^ 和] 中间的其他字符
|
?
|
其前面的字符不出现或出现一次 |
*
|
其前面的字符不出现或出现多次 |
+
|
其前面的字符出现一次或多次 |
字符输出函数
sprintf(format,expr-list)
按指定格式(format)将参数列表 expr-list 构造成字符串然后返回。
时间函数
systime
返回从 Epoch 以来到当前时间的秒数(在POSIX系统上,Epoch 为1970-01-01 00:00:00 UTC)。
mktime(dataspec)
将字符串dataspec
转换为与systime
风格的时间戳,dataspec
字符串的格式为 YYYY MM DD HH MM SS。
strftime([format [, timestamp[, utc-flag]]])
根据 format 指定的格式将时间戳 timestamp 格式化。
日期格式说明如下:
SN | 描述 | SN | 描述 |
---|---|---|---|
%a | 星期缩写 | %A | 星期全称 |
%b | 月份缩写 | %B | 月份全称 |
%c | 本地日期与时间 | %C | 世纪数 |
%d | 十进制日期(01-31) | %D | 等价于 %m/%d/%y. |
%e | 日期,如果只有一位数字则用空格补齐 | ||
%F | 等价于 %Y-%m-%d | ||
%G | 标准周所在年份的全称 | %g | 标准周所在的年份模除100 |
%h | 等价于 %b | ||
%H | 24小时格式的小时[00-23] | %I | 12小时格式的小时[00-12] |
%j | 一年中的第几天[001-366] | ||
%m | 月份[01-12] | %M | 分钟数[00-59] |
%n | 换行符 (ASCII LF) | ||
%p | 十二进制表示法(AM/PM) | ||
%r | 等价于 %I:%M:%S %p | %R | 等价于 %H:%M。 |
%S | 时间的秒数值(00-60) | ||
%t | 制表符 (tab) | %T | 等价于 %H:%M:%S。 |
%u | 以数字表示的星期(1-7),1 表示星期一。 | ||
%U | 一年中星期序号 | %V | 一年中星期序号 |
%w | 星期[0-6],0表示星期日 | %W | 一年中星期序号s |
%x | 本地日期表示 | %X | 本地时间表示 |
%y | 年份模除100 | %Y | 十进制表示的完整年份。 |
%z | 时区,表示格式为+HHMM | ||
%Z | 时区名称或缩写,如果时区待定则无输出。 |
其中,%U
以周日为一周开始;%V, %W
以周一作为一周开始;
%z
的表示格式为+HHMM(例如,格式要求生成的 RFC 822或者 RFC 1036 时间头)
其它函数
close(expr)
|
关闭管道的文件 |
delete
|
从数组中删除元素 |
exit
|
终止脚本执行 |
flush
|
刷新打开文件或管道的缓冲区 |
getline
|
读入下一行 |
next
|
停止处理当前记录,并且进入到下一条记录的处理过程 |
nextfile
|
停止处理当前文件,从下一个文件第一个记录开始处理。 |
system
|
执行特定的命令,返回其退出状态,0表示成功,否则表示失败 |
文本处理神器Awk语言详解相关推荐
- Linux文本处理必杀技之awk应用详解
AWK是一个优良的文本处理工具,Linux及Unix环境中现有的功能最强大的数据处理引擎之一.这种编程及数据操作语言(其名称得自于它的创始人阿尔佛雷德·艾侯.彼得·温伯格和布莱恩·柯林汉姓氏的首个字母 ...
- linux awk命令详解,使用system来内嵌系统命令,批量github,批量批下载视频, awk合并两列...
linux awk命令详解 简介 awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分 ...
- Linux下的awk用法详解
Linux下的awk用法详解 一.awk介绍 二.awk的语法 三.awk常见用法 四.awk其他用法 五.awk语言特性 一.awk介绍 1.AWK 是一种处理文本文件的语言,是一个强大的文本分析工 ...
- 深度学企业linux awk命令详解与应用(下篇)
开篇语: 我们在<一篇速学企业linux awk命令详解与应用(上篇)>中介绍了 awk 的基本用法,其实在awk 脚本程序中,还支持使用一些编程语言,比如变量.数组.分支结构(if-th ...
- linux下awk命令详解,Linux文件处理awk命令-linux awk命令详解-嗨客网
Linux文件处理awk命令详解教程 Linux awk命令说明 awk 是一个强大的文本分析工具,相对于 awk 有 3 个不同版本: awk.nawk 和 gawk,未作特别说明,一般指 gawk ...
- Liunx awk命令详解
Liunx awk命令详解 简介 awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分 ...
- Drools 规则语言详解(上)
http://www.blogjava.net/guangnian0412/archive/2006/06/09/51574.html http://www.blogjava.net/guangnia ...
- 从文本界面安装RHEL5操作系统详解
从文本界面安装RHEL5操作系统详解 译: -从图形化界面安装系统,按回车键 -从文本界面安装系统,输入linux text 回车 -使用功能键列出下面更多的信息 [F1-主界面 ...
- shell awk命令详解
shell awk命令详解 awk原理 格式 实操 相关内建变量 简易需求 进阶操作 高阶操作 awk原理 逐行读取文本,默认时以空格或tab键为分隔符进行分隔,将分隔所得的各个字段保存到内建变量中, ...
最新文章
- linux内存源码分析 - 内存压缩(同步关系)
- hbase RowFilter如何根据rowkey查询以及实例实现代码
- 高级SQL优化(三) 常用优化工具 ——《12年资深DBA教你Oracle开发与优化——性能优化部分》...
- pythonrequests解析_Python requests获取网页常用方法解析
- python网址太长_Python GUI-长链转短链
- Javacript中(function(){})() 与 (function(){}()) 区别 {转}
- emacs VS vim 替换为回车符
- 【ML小结12】隐马尔科夫模型HMM
- HFSS - 倒F天线的设计与仿真
- extremecomponents相关大全
- 什么软件可以让手机使用免费WiFi上网
- word把选择答案弄到题目里_将Word解答中的答案项批量填入题干
- 搭建本地服务器中遇到无法启动FTP站点问题
- [BZOJ2938] 病毒
- LaTeX 多层列举 条目 编号
- 从零开始,手把手教你如何在Ubuntu下编译VLC-Android源码
- 景甜成为特步新晋品牌代言人
- 糊里糊涂违背了规则,硅胶制品很是懊悔
- 2018年值得一看的搞笑电视剧!
- android 打开手机存储空间不足,手机存储空间不足?清清缓存吧(Android手机)