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。设置RSTART和RLENGTH的值 |
split(s ,a) | 字符串分割 |
split(s ,a ,fs) | 利用fs把s 分裂成数组a,返回元素的个数。如果没有给出fs,则使用FS。数组分割和字段分割采用同样的方式 |
44(56)!例子有待添加!未完待续…
gsub(/b/,"&a&")
test.txt1 a
2 bab
3 csubstr(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.