Linux 三剑客之AWK

3. Awk

3.1 语法

AWK 命令模式:地址+动作
awk '/search pattern/ {actions}' file

地址通过正则表达式匹配得到,AWK默认采用ERE 模式。

3.2 参数

参数 含义
-F field-separator, 字段分隔符
-f 引入awk脚本
-v -v var=val, 设置变量值

字段 与 记录

记录: 类似于数据库中的一行数据,一行数据称为记录。默认通过换行符进行分隔。
字段: 一条记录由多个字段组成。默认采用空格进去分隔。

记录:Gawk is the GNU Project’s implementation of the AWK programming language.
字段:默认通过空格分隔字段,因而上述记录中,每个单词为一个字段。

3.3 变量

变量名 含义
RS 输入记录分隔符,默认换行
FS 输入字段分隔符,默认空格
ORS 输出记录分隔符,默认换行
OFS 输出字段分隔符,默认空格
NF 当前记录中字段数量
NR 当前已经处理的记录数
cat text
a:b:c 
awk:sed:grep

awk -F: '{print $1}' text
awk -v FS=: '{print $1}' text
awk -F: '{print $NF}' text

可以通过改变内置变量来控制各个分隔符。字段分隔符既可以通过改变内置变量,又可以通过参数-F进行指定。

3.4 脚本

3.3.1 表达式

操作符

操作符 含义
+, -, *, /, % 加,减,乘,除, 取余
++, - - 自增,自减 (both前置and后置)
&&,双竖线 逻辑操作
?: 三元条件, exp1 ? exp2 : exp3
…… ……

in: 判断数组是否存在某个索引。awk中数组都是关联数组

code> echo 1 | awk '{ my_arr[1] = 3; if (1 in my_arr) print "exist"; }'
out>  exist

delete: 删除数组中索引+元素。

code> echo 1 | awk '{my_arr[1] = 3; delete my_arr[1]; if (!(1 in my_arr)) print "not exist";}'
out > not exist

exit: 退出awk语句,停止执行。

BEGIN {
    print “begin";
}
{
    print "body"
}
END {
    print "end"
}

情况一:如果exit出现在BEGIN块中,则Body语句块与END语句块都会被执行。
情况二:如果exit出现在body块中,则BEGIN,END语句块会被执行
情况三:如果exit出现在END块中,则BEGIN,body语句块被执行。

 BEGIN {
     print "begin"
 }
 {
     print "body1"
     exit 1
     print "body2"
 };
 END {
     print "end"
 };

 code> echo 1 | awk -f test.awk 
 out > begin
       body1
       end

break: 循环控制
continue 循环控制

3.3.2 语句

if (condition) statement [ else statement ]
while (condition) statement
do statement while (condition)
for (expr1; expr2; expr3) statment
for (var in array) statement

3.3.3 函数

自定义函数

function function_name(parameter list) { statements }

NOTE: 函数参数为局部变量,而函数内部定义的变量为全局变量

cat test.awk
function myawk(text)
{
    my_text = text" world!"
}

{
    myawk("hello")
    print my_text
}

---------------
echo 1 | awk -f test.awk
hello world!

内置函数

数学函数
sqrt
sin
rand
srand

echo 1 | awk '{srand(); print rand();}' 

字符串函数
length
tolower
toupper

index(s, t):返回s中匹配t的位置。

code> echo 1 | awk '{s="spch2008"; print index(s, "2008");}'
out > 5

match(s, r): 在s中匹配r,返回匹配s的位置。内置变量RSTART返回匹配位置,RLENGTH返回匹配长度。

code> echo 1 | awk '{s="spch2008"; match(s, "2008"); print RLENGTH;}'
out > 4

NOTE: index 与 match的区别:t表示普通串,而r表示可以使用正则。

split(s, a, [, r]): 将字符串s,以r分隔,分隔后,放于数组a中;返回数组大小。

code> echo 1 | awk '{s="a:b:c:d"; split(s, a, ":"); for(slot in a) printf "%s ", a[slot]}'
out > d a b c

Note: for (item in array) 语句不保证按顺序输出,若要按顺序输出,采用for(i = 1; i < n; i++)

sprintf(fmt, expr-list):类似C的sprintf,格式化字符串。通过返回值,得到格式的字符串。

code> echo 1 | awk '{print sprintf("Hello %s", "Tom")}'
out > Hello Tom

strtonum(str): 字符串转数字。若字符串有前导0,则认为是8进制;若前导0x,则认为16进制。

code> echo 1 | awk '{print strtonum("0x10")}'
out > 16

sub(r, s, [, t]): 将t中,匹配r的部分,替换成s。若t为空,则使用$0

code> echo 1 | awk '{t="spch2008"; sub("/2008/", "1234", t); print t}'
out > spch1234

substr(s, i [,n]): 字符串截取。从位置i开始,截取n个;若n为空,则截取到字符串尾。

code> echo 1 | awk '{print substr("spch2008", 5, 4)}'
out > spch2008

IO函数

print: 简单打印
printf: 类似于C的printf

echo 1 | awk '{msg = "Hello"; printf "%s World!\n", msg;}'

next: 停止对当前记录进行任何规则得处理,强制处理下一条记录。

你可能感兴趣的:(linux,正则,grep-sed,linux-awk)