awk
awk是一种编程语言,用于在linux/unix下对文本和数据进行处理。
- 数据可以来自标准输入(stdin)、一个或多个文件
- 支持用户自定义函数以及动态正则表达式等先进功能
- 有很多内建的功能,比如数组、函数等,和c语言类似
awk命令
格式如下
awk [options] [-v var=value]... <script> <file>...
awk [options] -f <scriptfile> [-v var=value]... <file>...
选项 | 说明 |
---|---|
-F FS | 指定输入分隔符,可以是字符串或正则表达式 |
-v VAR=VALUE | 赋值给一个用户定义变量,并传递给awk |
-f SCRIPTFILE | 从脚本文件中读取awk命令 |
-m[fr] VAL | 对val值设置限制 |
-mf选项限制分配给val的最大块数目 -mr选项限制分配给val的记录的最大数目 这两个功能是Bell实验室版awk的扩展功能,在标准awk中不适用
awk脚本
基本结构
awk 'BEGIN{ commands } pattern{ commands } END{ commands }'
工作原理
- 执行BEGIN{ commands }语句块中的语句
- 从文件或标准输入(stdin)逐行读取数据,执行pattern{ commands }语句块,直到输入流末尾
- 执行END{ commands }语句块中的语句
BEGIN语句块是一个可选的语句块,比如变量初始化、打印输出表格的表头等语句通常可以写在BEGIN语句块中。 END语句块也是一个可选的语句块,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成 pattern语句块中的通用命令是最重要的部分,它也是可选的。
如果没有提供pattern语句块,则默认执行{ print },即打印每一个读取到的行,awk读取的每一行都会执行该语句块
模式和操作
awk脚本是由模式和操作组成的
模式
模式(PATTERN)可以是以下任意一个:
- /正则表达式/:使用通配符的扩展集
- 关系表达式:使用运算符进行操作,可以是字符串或数字的比较测试。
- 模式匹配表达式:用运算符~(匹配)和 ~!(不匹配)
- BEGIN语句块、PATTERN语句块、END语句块
操作
操作由一个或多个命令、函数、表达式组成,之间由换行符或分号隔开,并位于大括号内
- 变量或数组赋值
- 输出命令
- 内置函数
- 控制流语句
内置变量(预定义变量)
注意: [A][N][P][G]前缀表示第一个能够支持该变量的工具
[A]=awk、[N]=nawk、[P]=POSIXawk、[G]=gawk,区别参见这里
变量 | 说明 |
---|---|
$0 | 执行过程中当前行的文本内容 |
$n | 当前记录的第n个字段 |
[N] ARGC | 命令行参数的个数 |
[N] ARGV | 包含命令行参数的数组 |
[G] ARGIND | 命令行中当前文件的位置(从0开始算) |
[G] CONVFMT | 数字转换格式(默认值为%.6g) |
[P] ENVIRON | 环境变量相关的数组 |
[N] ERRNO | 最后一个系统错误的描述 |
[G] FIELDWIDTHS | 字段宽度列表(用空格键分隔) |
[A] FILENAME | 当前输入文件的名称 |
[A] FS | 输入字段分隔符(默认是任何空白符) |
[A] RS | 输入记录分隔符(默认是一个换行符) |
[G] IGNORECASE | 如果为真,则进行忽略大小写的匹配 |
[A] NF | 表示字段数,在执行过程中对应于当前的字段号 |
[A] NR | 表示记录数,在执行过程中对应于当前的行号 |
[P] FNR | 同NR,但相对于当前文件 |
[A] OFMT | 数字的输出格式(默认值是%.6g) |
[A] OFS | 输出字段分隔符(默认值是一个空格) |
[A] ORS | 输出记录分隔符(默认值是一个换行符) |
[N] RSTART | 由match函数所匹配的字符串的第一个位置 |
[N] RLENGTH | 由match函数所匹配的字符串的长度 |
[N] SUBSEP | 数组下标分隔符(默认值是34) |
ARGC -> argument count | ARGV -> argument vector | FMT -> format | ENVIRON -> environment | F -> field | R -> record | O -> output
运算与判断
作为一种程序设计语言所应具有的特点之一,awk支持多种运算,这些运算与C语言提供的基本相同。
- awk提供了一系列内置的运算函数(如log、sqr、cos、sin等)
- awk提供了一些对字符串进行操作的函数(如length、substr等)
- awk中允许进行多种测试,还提供了模式匹配表达式~(匹配)和~!(不匹配)
算术运算符
运算符 | 描述 |
---|---|
+ | 正号 |
- | 负号 |
+ | 加法 |
- | 减法 |
* | 乘法 |
/ | 除法 |
% | 求余 |
++ | 自增 |
-- | 自减 |
^ | 求幂 |
** | 求幂 |
所有用作算术运算符进行操作,操作数自动转为数值,所有非数值都变为0
关系运算符
运算符 | 描述 |
---|---|
< | 小于 |
< = | 小于等于 |
> | 大于 |
>= | 大于等于 |
== | 等于 |
!= | 不等于 |
注意:小于和等于号之间没有空格,由于Markdown的原因多了一个空格
赋值运算符
运算符 | 描述 |
---|---|
= | 赋值 |
+= | 自增并赋值给当前变量 |
-= | 自减并赋值给当前变量 |
*= | 自乘并赋值给当前变量 |
/= | 自除并赋值给当前变量 |
%= | 求余并赋值给当前变量 |
^= | 求幂并赋值给当前变量 |
**= | 求幂并赋值给当前变量 |
逻辑运算符
运算符 | 描述 |
---|---|
&& | 逻辑与 |
| | | 逻辑或 |
! | 逻辑非 |
正则运算符
运算符 | 描述 |
---|---|
~ | 匹配正则表达式 |
~! | 不匹配正则表达式 |
其它运算符
运算符 | 描述 |
---|---|
$ | 引用字段 |
?: | C三元条件表达式 |
in | 数组中是否存在某值 |
条件判断
为了方便判断和阅读,最好将多个语句用{}括起来
if(表达式)
语句1
else
语句2
if(表达式)
{语句1}
else if(表达式)
{语句2}
else
{语句3}
每条命令语句后面可以用
;
分号结尾
循环语句
while语句
while(表达式)
{语句}
do
{语句} while(条件)
for循环
for(变量 in 数组)
{语句}
for(初始变量;结束条件;表达式)
{语句}
退出循环
break
退出当层循环continue
跳过本次循环next
进入下一次循环- exit
跳到END块,如果没有END块则终止脚本的执行
数组
awk的数组和c语言类似,但有以下不同
- 数组不必提前声明,也不必声明大小
- 数组元素用0或空字符串来初始化,由上下文而定
- 数组下标是从1开始,与C数组不一样
函数 | 描述 |
---|---|
length | 获取数组的长度 |
asort | 对数组进行排序,返回数组长度 |
更多内容参考这里的数组部分
数学计算
公式中的参数值都是弧度,角度、弧度、三角函数的知识参考这里
ln - 以自然对数e为底) lg - 以10为底 logab - 以a为底,b为真数
函数 | 描述 |
---|---|
sin( x ) | 返回 x 的正弦,x 是弧度 |
cos( x ) | 返回 x 的余弦, x 是弧度 |
atan2( y, x ) | 返回 y/x 的反正切 |
exp( x ) | 返回 x 幂函数 |
log( x ) | 返回 x 的自然对数 |
sqrt( x ) | 返回 x 平方根 |
int( x ) | 返回 x 的取整值 |
rand( n ) | 返回任意数字 n,其中 0 < = n < 1 |
srand( [expr] ) | 将 rand 函数的种子值设置为 Expr 参数的值,并返回先前的种子值 |
srand 如果省略 Expr 参数则使用某天的时间。
字符串
函数
注意:字符串函数中的起始编号都是1,查找失败返回都是0。缺省的字符串参数是正在处理的行
函数 | 描述 |
---|---|
sub( Ere, Repl, [ In ] ) | 用 Repl 参数指定的字符串替换 In 中匹配的部分并返回替换的数量 |
gsub( Ere, Repl, [ In ] ) | 除了替换所有匹配外,和 sub 函数一样 |
index( String1, String2 ) | 在 String1 查找首次String2出现的位置 |
length [(String)] | 返回 String 参数指定的字符串的长度(以字符为单位) |
blength [(String)] | 返回 String 参数指定的字符串的大小(以字节为单位) |
substr( String, M, [ N ] ) | 从 M 处开始,截取N个长度的子串,N省略则到末尾 |
match( String, Ere ) | 在 String1 查找首次 Ere 匹配的位置。RSTART 特殊变量设置为返回值,未匹配则为0。RLENGTH 特殊变量设置为匹配的字符串的长度。未匹配则为-1 |
split( String, A, [Ere] ) | 将 String 参数指定的参数分割为数组A,并返回数组的长度。此分隔可以通过 Ere 参数指定的扩展正则表达式进行,或用当前字段分隔符(FS 特殊变量)来进行(如果没有给出 Ere 参数) |
tolower( String ) | 转换为小写,映射由当前语言环境的 LC_CTYPE 定义 |
toupper( String ) | 转换为大写,映射由当前语言环境的 LC_CTYPE 定义 |
printf(Format, Expr, Expr, . . . ) | 根据 Format 参数来格式化 Expr 参数指定的表达式并返回最后生成的字符串 |
格式化
格式化参照 printf
命令和c语言的 printf()
函数
时间
函数
格式 | 描述 |
---|---|
mktime( YYYY MM dd HH MM ss[ DST]) | 生成时间格式串 |
strftime([format [, timestamp]]) | 格式化时间输出 |
systime() | 返回从1970年1月1日开始到当前时间(不计闰年)的整秒数 |
格式化
格式 | 描述 |
---|---|
%a | 星期的缩写(Sun) |
%A | 星期的完整写法(Sunday) |
%b | 月名的缩写(Oct) |
%B | 月名的完整写法(October) |
%c | 本地日期和时间 |
%d | 十进制日期 |
%D | 日期 (08/10/25) |
%e | 日期,如果只有一位会补上一个空格 |
%H | 用十进制表示24小时格式的小时 |
%I | 用十进制表示12小时格式的小时 |
%j | 从1月1日起一年中的第几天 |
%m | 十进制表示的月份 |
%M | 十进制表示的分钟 |
%p | 12小时表示法(AM/PM) |
%S | 十进制表示的秒 |
%U | 十进制表示的一年中的第几个星期(星期天作为一个星期的开始) |
%w | 十进制表示的星期几(星期天是0) |
%W | 十进制表示的一年中的第几个星期(星期一作为一个星期的开始) |
%x | 重新设置本地日期(08/10/25) |
%X | 重新设置本地时间(12:00:00) |
%y | 两位数字表示的年(19) |
%Y | 四位数字表示的年(99) |
%Z | 时区(PDT) |
%% | 百分号(%) |
其他函数
格式 | 描述 |
---|---|
close( Expression ) | 用同一个带字符串值的 Expression 参数来关闭由 print 或 printf 语句打开的或调用 getline 函数打开的文件或管道。如果文件或管道成功关闭,则返回 0;其它情况下返回非零值。如果打算写一个文件,并稍后在同一个程序中读取文件,则 close 语句是必需的 |
system( command ) | 执行 Command 参数指定的命令,并返回退出状态。等同于 system 子例程 |
Expression | getline [ Variable ] | 从来自 Expression 参数指定的命令的输出中通过管道传送的流中读取一个输入记录,并将该记录的值指定给 Variable 参数指定的变量。如果当前未打开将 Expression 参数的值作为其命令名称的流,则创建流。创建的流等同于调用 popen 子例程,此时 Command 参数取 Expression 参数的值且 Mode 参数设置为一个是 r 的值。只要流保留打开且 Expression 参数求得同一个字符串,则对 getline 函数的每次后续调用读取另一个记录。如果未指定 Variable 参数,则 $0 记录变量和 NF 特殊变量设置为从流读取的记录 |
getline [ Variable ] < Expression | 从 Expression 参数指定的文件读取输入的下一个记录,并将 Variable 参数指定的变量设置为该记录的值。只要流保留打开且 Expression 参数对同一个字符串求值,则对 getline 函数的每次后续调用读取另一个记录。如果未指定 Variable 参数,则 $0 记录变量和 NF 特殊变量设置为从流读取的记录 |
getline [ Variable ] | 将 Variable 参数指定的变量设置为从当前输入文件读取的下一个输入记录。如果未指定 Variable 参数,则 $0 记录变量设置为该记录的值,还将设置 NF、NR 和 FNR 特殊变量 |
使用示例
awk脚本非常复杂,需要结合示例学习,示例部分参考awk命令中的示例
参考
awk命令
Linux 的(cut,sed,awk,grep,sort)工具
awk、nawk、mawk、gawk的简答介绍
数学基础:角度,弧度,三角函数
LC_ALL=C的含义
linux系统locale的设定
Explain the effects of export LANG, LC_CTYPE, LC_ALL