AWK学习笔记-2.2Action

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)
    00a
    1e5001.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.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值