作用
awk主要是处理每一行的字段内的数据,默认的字段分隔符为空格或Tab。
awk 是一种处理文本文件的语言,是一个强大的文本分析工具。
awk 其实不仅仅是工具软件,还是一种编程语言。
awk 是以文件的一行内容为处理单位的。awk读取一行内容,然后根据指定条件判断是否处理此行内容,若此行文本符合条件,则按照动作处理文本,否则跳过此行文本,读取下一行进行判断。
语法
awk '条件类型1{操作1} 条件类型2{操作2} ...' filename
参数
注意单引号是awk的固定用法,在内部应该使用双引号。
-F
‘:’
指定分隔符-f
filename
调用脚本文件-v
定义变量 var=value
- ‘ ‘
引用代码块 - BEGIN
初始化代码块,在对每一行进行处理之前,初始化代码,主要是引用全局变量,设置FS分隔符 - /string/
匹配代码块,可以是字符串或正则表达式 - {}
命令代码块,包含一条或多条命令 - ;
在命令代码块内,多条命令使用分号分隔 - END
结尾代码块,在对每一行进行处理之后再执行的代码块,主要是进行最终计算或输出结尾摘要信息
变量
变量名称 | 意义 |
---|---|
$0 | 表示当前整行 |
$# | 表示当前第#个字段 |
NF | 每一行($0)拥有的字段总数 |
NR | 目前awk所处理的是第几行数据 |
FS | 目前的分隔符,默认为空格。 |
FILENAME | 当前文件名 |
RS | 行分隔符,用于分割每一行,默认是换行符。 |
OFS | 输出字段的分隔符,用于打印时分隔字段,默认为空格。 |
ORS | 输出记录的分隔符,用于打印时分隔记录,默认为换行符。 |
OFMT | 数字输出的格式,默认为%.6g。 |
逻辑运算符
运算符 | 意义 |
---|---|
< | 小于 |
> | 大于 |
<= | 小于等于 |
>= | 大于等于 |
== | 等于 |
!= | 不等于 |
~ | 匹配,与==相比不是精确比较 |
!~ | 不匹配,不精确比较 |
&& | 逻辑与 |
|| | 逻辑或 |
函数
print
参数可以是变量、数值或者字符串。字符串必须用双引号引用,参数用逗号分隔。如果没有逗号,参数就串联在一起而无法区分。这里,逗号的作用与输出文件的分隔符的作用是一样的,只是后者是空格而已。printf
其用法和c语言中printf基本相似,可以格式化字符串,输出复杂时,printf更加好用,代码更易懂。toupper()
字符转为大写。- tolower()
字符转为小写。 - length()
返回字符串长度。 - substr()
返回子字符串。 - substr($1,2)
返回第一个字段,从第2个字符开始一直到结束。 - substr($1,2,3)
返回第一个字段,从第2个字符开始开始后的3个字符。 - sin()
正弦 - cos()
余弦 - sqrt()
平方根 - rand()
随机数 getline
next
结束当前行,开始判断下一行。
getline
getline 是awk里用于输入重定向的一个函数,他可以从标准输入/一个管道/文件读取输入, 而不只是从当前被处理的文件来处理, 他取得输入的下一行并给NF,NR,FNR等内置变量赋值,
如果找到一条记录getline则返回1;
如果到了文件结束(EOF),则返回0;
如果错误则返回-1。
当其左右无重定向符 | 或 < 时,getline作用于当前文件,读入当前文件的第一行给其后跟的变量var 或$0(无变量);应该注意到,由于awk在处理getline之前已经读入了一行,所以getline得到的返回结果是隔行的。
当其左右有重定向符 | 或 < 时,getline则作用于定向输入文件,由于该文件是刚打开,并没有被awk读入一行,只是getline读入,那么getline返回的是该文件的第一行,而不是隔行
Variant | Effect |
getline | Sets $0, NF, FNR, and NR |
getline var | Sets var, FNR, and NR |
getline < file | Sets $0 and NF |
getline var < file | Sets var |
command | getline | Sets $0 and NF |
command | getline var | Sets var |
command |& getline | Sets $0 and NF. This is a gawk extension |
command |& getline var | Sets var. This is a gawk extension |
使用实例
创建一个测试文件。分隔符为空格。
No Name class age
1 Xiaoming 1 10
2 Zhangsan 2 11
3 Lisi 3 9
指定分隔符
使用选项改变分隔符
[root@192 Ethan]# echo $PATH | awk -F: '{for(i=1;i<NF;i++) print $i}'
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
使用变量改变分隔符
[root@192 Ethan]# echo $PATH | awk 'BEGIN{FS=":"} {for(i=1;i<NF;i++) print $i}'
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
条件判断
布尔值判断
[root@192 Ethan]# awk 'NR==1 {printf "%10s %10s %10s %10s\n",$1,$2,$3,$4};NR>1 {printf "%10d %10s %10d %10d\n",$1,$2,$3,$4}' awk.test
No Name class age
1 Xiaoming 1 10
2 Zhangsan 2 11
3 Lisi 3 9√
if语句判断
[root@192 Ethan]# awk '{if(NR==1) printf "%10s %10s %10s %10s\n",$1,$2,$3,$4};{if(NR>1) printf "%10d %10s %10d %10d\n",$1,$2,$3,$4}' awk.test
No Name class age
1 Xiaoming 1 10
2 Zhangsan 2 11
3 Lisi 3 9
正则表达式
[root@192 Ethan]# awk '/Lisi/ {printf "%10d %10s %10d %10d\n",$1,$2,$3,$4}' awk.test
3 Lisi 3 9
数值运算
[root@192 Ethan]# awk 'NR>1 {print $1+10}' awk.test
11
12
13
参考资料
https://www.cnblogs.com/panscience/p/4685698.html
http://club.topsage.com/thread-357784-1-1.html