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 }'

工作原理

  1. 执行BEGIN{ commands }语句块中的语句
  2. 从文件或标准输入(stdin)逐行读取数据,执行pattern{ commands }语句块,直到输入流末尾
  3. 执行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

Copyright © zhujipeng 2017 all right reserved,powered by Gitbook 该文件修订时间: 2017-11-04 14:57:24

results matching ""

    No results matching ""