AWK学习笔记-2.2Action

来源:互联网 发布:vc2015 windows 7 编辑:程序博客网 时间:2024/06/03 21:37

Actions

Expressions

  • Constants 数字,字母

  • Variables 自定义,内置,列

    自定义变量只能由数字,字母,下划线_组成,不能以数字开头

Field Variables

用表达式表示字段 $1~$n,$NF

  • Arithmetic Operators 算术运算符= += -= *= I= %= “’=
    • Comparison Operators 比较运算符< <= == I= > >=
    • Logical Operators 逻辑运算符 && || !
    • Conditional Expressions 条件表达式 ?:
    • Assignment Operators 赋值运算符 +=, -=, *=, 1=, %=, ^=
    • matching operators 匹配符号 - and I -
    • increment and decrement operators 自增自减符号 ++and –

Built-In Variables.

变量名 含义 缺省值 ARGC 命令行参数个数 - ARGV 命令行参数数组 - FILENAME 当前输入文件的名字 - FNR 当前记录数 - NF 当前记录中的字段个数,即有多少列 - NR 已经读出的记录数,即行号,从1开始 - OFMT 数字的输出格式 “%.6g” FS 列分隔符(为空时按照每个字符分隔) “” OFS 列输出分隔符 “” ORS 行输出分隔符 “\n” RS 行输入的分隔符 “\n” RLENGTH 被匹配函数匹配的字符串首 - RSTART 被匹配函数匹配的字符串首 - SUBSEP 数组下标分隔符 “\034”

【SUBSEP 数组下标分隔符】

awk中的数组只接受字串当它的下标,比如:Arr[“John”]。但awk中仍然可使用数字当数组的下标,甚至可使用多维的数组,比如Arr[2,20]。事实上,awk在接受Arr[2,20]之前,就已先把其下标转换成字串”2/03420″,之后便以Arr[“2
/03420”] 代替Arr[2,20]

Built-In Arithmetic Functions. 内置函数

函数名 返回值 atan2(y,x) y/x的反正切,其返回值为[-pi,+pi]之间的一个数 cos(x) cosine of x, with x in radians exp(x) exponential function of x, ex int(x) 对x取整 log(x) 以e为底,x的对数 rand() 随机数[0,1) sin(x) 正弦 (x是弧度) sqrt(x) 开方 srand(x) 以x为种子生成随机数,缺省时候以时间

【atan2】

atan2返回值解释:

在[三角函数]中,两个参数的[函数]atan2是[正切函数]的一个变种。对于任意不同时等于0的实参数x和y,atan2(y,x)所表达的意思是坐标原点为起点,指向(y,x)的射线在坐标平面上与x轴正方向之间的角的角度度。当y>0时,射线与x轴正方向的所得的角的角度指的是x轴正方向绕逆时针方向到达射线旋转的角的角度;而当y<0时,射线与x轴正方向所得的角的角度指的是x轴正方向绕顺时针方向达到射线旋转的角的角度。

Strings as Regular Expressions. 字符串作为正则表达式

在BEGIN的代码块种声明正则表达式的字符串

shell
#显示含有有效浮点数的输入行
BEGIN {
sign = "[+-]?"
decimal= "[0-9]+[.]?[0-9]*"
fraction= "[.][0-9]+"
exponent= "([eEl" sign "[0-9]+)?"
number= "^" sign"(" decimal "|" fraction ")" exponent "$"
}
$0 ~ number

$0 ~ /(\+|-)[0-9]+/$0 ~ "(\\+|-)[0-9]+" 是相等的

Built-In String Functions. 内置字符串函数

下表中,r表示正则表达式(或者作为一个字符串或用斜杠括起来),s和t是字符串表达式,n和p是整数。

函数 描述 sub(r,s,t) 在字符串t中用s替换正则表达式t的首次匹配。如果成功则返回1,否则返回0。如果没有给出t,默认为$0 gsub(r,s,t) 全局替换,将t中的r替换为s,如果没有给出t,默认为$0 substr(s,p) 在s中,从p位置开始截取字符串 substr(s,p,n) 在s中,从p位置开始,到n位置结束截取字符串 index(s,t) 返回t第一次在s中出现的位置,从 1 开始编号。如果不出现,则返回 0。 length(s) 返回字符串的长度(字符形式)如果未给出 s 参数,则返回整个记录($0 记录变量)的长度 blength(s) 返回 String 参数指定的字符串的长度(字节为单位)如果未给出 s 参数,则返回整个记录($0 记录变量)的长度 match(s ,r) 返回r 在s 中出现的位置,不出现时为0。设置RSTARTRLENGTH的值 split(s ,a) 字符串分割 split(s ,a ,fs) 利用fs把s 分裂成数组a,返回元素的个数。如果没有给出fs,则使用FS。数组分割和字段分割采用同样的方式

44(56)!例子有待添加!未完待续…

  • gsub(/b/,"&a&")test.txt

    1 a
    2 bab
    3 c

  • substr(s,p,n)

    使用substr截取之后会以OFS分割。当然也可以直接指定

    { s = s substr ($1 , 1 , 3 ) " " }END { print s }

    USS Can Chi USA Bra Ind Mex Fra Jap Ger Eng

更多可以参考网上的解释内置函数

Number or String?

之前提到,awk中有两种格式,数字和字符串

数字和字符串之间有时会根据你的操作进行转换

$1==$2

  • 如果$1和$2为下方任意一个的话,返回真。因为都是1

    1, 1.0, +1, 1e0, 0.1e+1, 10E-1, 001

  • 1|2 结果 0 (null) 0.0 (null) 0 0a 1e500 1.0e500
  • 没有初始化的变量默认为0或者“”

    不存在的列只会被定义为值为“”的null

  • 强制转换:

    • number “” 将数字转化成字符

    $1 "" == $2 对两列进行字符串之间的比较

    • string + 0 将字符转化成数字

    $1 + 0 == $2 + 0

    • 字符串的数值是数字的字符串的最长前缀的值

    BEGIN { print "1E2"+0, "12E"+0, "E12"+0, "1X2Y3"+0 }

    100 12 0 1

    • 数字转化成字符串(格式由OFMT决定)

    BEGIN { print 1E2 "", 12E-2 "", E12 "", 1.23456789 "" }

    100 0.12 1.23457

Control-Flow Statements 控制流程语句

  • {statements}
  • for(expression1; expression2;expression3) statement
  • for(variable in array) statement
  • if (expression) statement
  • if (expression) statement1 else statement2
  • do statement while(expression)
  • while (expression) statement
  • break continue
  • exit
  • exit expression

  • next 语句读取下一条记录,再从头执行代码

    cat data

    1 a

    2 b

    3 c

    awk '/^2/{print $2;next}{print $0}' file

    1 a

    b

    3 c

    如果匹配不到开头为2的记录,就打印$0
    如果匹配到了开头为2的记录,就打印\$2,这里如果没有next,会继续再打印\$0

Arrays

awk中数组不需要定义,也不声明数组长度。

/Asia/  {pop["Asia"] += $3 }/Europe/{pop["Europe"] += $3}END     {print "Asian population is",            pop["Asia"], "million."         print "European population is",            pop[ "Europe"] , "million."    }

Asian population is 2173 million.
European population is 172 million.

  • 遍历数组in
BEGIN   {FS = "\t" }        {pop[$4] += $3 }END     {for (name in pop)            print name, pop[name]        }

North America 340
South America 134
Asia 2173
Europe 172

  • 判断数组中是否存在某元素

subscript in A 如果A[subscript]存在,整个表达式的值为0,否则为1

if (“Africa” in pop) …

if (pop[“Africa”] !=”“) 将可能创建一个新元素!

  • 删除元素

    delete array[subscript]

    for (i in pop) delete pop[i] 删除所有元素

    新版的gawk可以用简单的delete array命令删除整个数组。

  • split (str, arr ,fs) 按照fs的方式将str分割开并存储在arr数组中。fs缺省将会使用FS

    split("7/4/76",arr,"/")

    7 inarr [ ” 1” ] , 4 in arr [ “2” ] , and 76 in arr [ “3”].

  • Multidimensional Arrays. 多维数组

for (i = 1; i <= 10; i++)    for (j = 1; j <= 10; j++)        arr[i, j] = 0

​ * awk实际用arr[i SUBSEP j]来代替arr[i,j]。SUBSEP的默认值是”\034”,还记得吗?内置变量

​ * if ((i, j) in arr) 方式来使用判断是否有某个位置的元素

​ * for (k in arr) 遍历数组,split(k, x, SUBSEP)

for (i in arr) {    split(i, a, SUBSEP);    printf "%s\t%s\t%s\n", a[1], a[2], arr[a[1], a[2]]}# 对于数值,还可以这样遍历for (i=0; i<M; i++) {    for (j=0; j<N; j++) {        print arr[i, j]    }

​ * split(string, array [, fs [, seps ] ])

​ 将string按fs分割存储在array[1], array[2], …, 并将分隔符依次存储在seps[1], seps[2], …, 最后返回被分割的数目。举例如下:

split(“cul-de-sac”, a, “-“, seps)
a[1] = “cul”
a[2] = “de”
a[3] = “sac”

seps[1] = “-”
seps[2] = “-”

函数返回值为3

​ * 数组元素本身不能是数组。

P.S.数组的下表是String,但是因为数字和字母的数值一样,所以A[1]和A[“1”]相等。

但是01和1不同,01之后是字符串10,而1之后是字符串2.

Arrays

awk中数组不需要定义,也不声明数组长度。

/Asia/  {pop["Asia"] += $3 }/Europe/{pop["Europe"] += $3}END     {print "Asian population is",            pop["Asia"], "million."         print "European population is",            pop[ "Europe"] , "million."    }

Asian population is 2173 million.
European population is 172 million.

  • 遍历数组in
BEGIN   {FS = "\t" }        {pop[$4] += $3 }END     {for (name in pop)            print name, pop[name]        }

North America 340
South America 134
Asia 2173
Europe 172

  • 判断数组中是否存在某元素

subscript in A 如果A[subscript]存在,整个表达式的值为0,否则为1

if (“Africa” in pop) …

if (pop[“Africa”] !=”“) 将可能创建一个新元素!

  • 删除元素

    delete array[subscript]

    for (i in pop) delete pop[i] 删除所有元素

    新版的gawk可以用简单的delete array命令删除整个数组。

  • split (str, arr ,fs) 按照fs的方式将str分割开并存储在arr数组中。fs缺省将会使用FS

    split("7/4/76",arr,"/")

    7 inarr [ ” 1” ] , 4 in arr [ “2” ] , and 76 in arr [ “3”].

  • Multidimensional Arrays. 多维数组

for (i = 1; i <= 10; i++)    for (j = 1; j <= 10; j++)        arr[i, j] = 0

​ * awk实际用arr[i SUBSEP j]来代替arr[i,j]。SUBSEP的默认值是”\034”,还记得吗?内置变量

​ * if ((i, j) in arr) 方式来使用判断是否有某个位置的元素

​ * for (k in arr) 遍历数组,split(k, x, SUBSEP)

for (i in arr) {    split(i, a, SUBSEP);    printf "%s\t%s\t%s\n", a[1], a[2], arr[a[1], a[2]]}# 对于数值,还可以这样遍历for (i=0; i<M; i++) {    for (j=0; j<N; j++) {        print arr[i, j]    }

​ * split(string, array [, fs [, seps ] ])

​ 将string按fs分割存储在array[1], array[2], …, 并将分隔符依次存储在seps[1], seps[2], …, 最后返回被分割的数目。举例如下:

split(“cul-de-sac”, a, “-“, seps)
a[1] = “cul”
a[2] = “de”
a[3] = “sac”

seps[1] = “-”
seps[2] = “-”

函数返回值为3

​ * 数组元素本身不能是数组。

P.S.数组的下表是String,但是因为数字和字母的数值一样,所以A[1]和A[“1”]相等。

但是01和1不同,01之后是字符串10,而1之后是字符串2.

0 0
原创粉丝点击