1、概述
awk是专门为文本处理设计的编程语言,是一门数据驱动的编程语言,与sed类似都是以数据驱动的行处理软件,主要用于数据扫描、过滤、统计汇总工作,数据可以来自标准输入、管道或者文件。
awk在20世纪70年代诞生与贝尔实验室。现在使用的版本是1988年发布的Gnu awk
1.1 awk的几个变体
下面是几个AWK的变体:
- AWK – 原先来源于 AT & T 实验室的的AWK
- NAWK – AT & T 实验室的AWK的升级版
- GAWK – 这就是GNU AWK。所有的GNU/Linux发布版都自带GAWK,它与AWK和NAWK完全兼容
1.2 awk典型用途
使用AWK可以做很多任务,下面是其中一些
- 文本处理
- 输出格式化的文本报表
- 执行算数运算
- 执行字符串操作等等
2、AWK工作流程基本语法
2.1 工作流程
AWK 执行的流程非常简单:读( Read )、执 行( Execute )与重复( Repeat )。下面的流程图描述出了 AWK 的工作流程:

2.2 语法结构
awk -[选项] 'BEGIN {awk-command-begin} {awk-command-body} END {awk-command-end}' 被执行文件
单引号包围的是整个 awk 程序。 单引号是必须存在的!!!! 双引号表示字符串,后面示例中有
2.2.1 awk常用选项
-v变量赋值 该选项将一个值赋予一个变量,它会在程序开始之前进行赋值。
awk -v name=Jerry 'BEGIN{printf "Name = %s\n", name}
Name = Jerry
--dump-variables[=file]该选项会输出排好序的全局变量列表和它们最终的值到文件中,默认的文件是 awkvars.out
$ awk --dump-variables ''
$ cat awkvars.out
ARGC: 1
ARGIND: 0
ARGV: array, 1 elements
BINMODE: 0
CONVFMT: "%.6g"
ERRNO: ""
FIELDWIDTHS: ""
FILENAME: ""
FNR: 0
FPAT: "[^[:space:]]+"
FS: " "
IGNORECASE: 0
LINT: 0
NF: 0
NR: 0
OFMT: "%.6g"
OFS: " "
ORS: "\n"
RLENGTH: 0
RS: "\n"
RSTART: 0
RT: ""
SUBSEP: "\034"
TEXTDOMAIN: "messages"
-
--help打印帮助信息 -
--lint[=fatal]该选项允许检查程序的不兼容性或者模棱两可的代码,当提供参数 fatal的时候,它会对待Warning消息作为Error。
$ awk --lint '' /bin/ls
awk: cmd. line:1: warning: empty program text on command line
awk: cmd. line:1: warning: source file does not end in newline
awk: warning: no program text at all!
--posix:该选项开启严格的POSIX兼容--profile[=file]: 该选项会输出一份格式化后的程序到文件中,默认文件是awkprof.out
$ awk --profile 'BEGIN{printf"---|Header|--\n"} {print} END{printf"---|Footer|---\n"}' marks.txt > /dev/null
$ cat awkprof.out
# gawk 配置, 创建 Wed Oct 26 15:05:49 2016
# BEGIN 块
BEGIN {
printf "---|Header|--\n"
}
# 规则
{
print $0
}
# END 块
END {
printf "---|Footer|---\n"
}
--traditional该选项会禁止所有的gawk规范的扩展。-V输出版本号-F指定字段分隔符。自定义输入数据的字段分隔符(默认为空格或制表符)awk -F':' '{print $1, $NF}' /etc/passwd。-F等价于内置变量FS,也可在BEGIN块中设置(如BEGIN{FS=":"})。-f从文件读取Awk命令,替代命令行直接输入。复杂脚本复用或长命令拆分,提升可维护性。awk -f demo.awk data.txt
2.2.2 BEGIN语句块
BEGIN语句块语法:
BEGIN {awk-commands}
BEGIN语句块在程序开始的使用执行,它只执行一次,在这里可以初始化变量。BEGIN是AWK的关键字,因此它必须为大写,注意,这个语句块是可选的。
2.2.3 BODY语句块
BODY语句块的语法:
/pattern/ {awk-commands}
BODY语句块中的命令会对输入的每一行执行,我们也可以通过提供模式来控制这种行为。注意,BODY语句块没有关键字。
2.2.4 END语句块
END语句块的语法
END {awk-commands}
END语句块在程序的最后执行,END是AWK的关键字,因此必须为大写,它也是可选的。
2.3 示例
2.3.1 示例文件
创建一个名为 marks.txt 的文件。其中包括序列号、学生名字、课程名称与所得分数
[root@entos7 awk_test]# cat marks.txt
1) Amit Physics 80
2) Rahul Maths 90
3) Shyam Biology 87
4) Kedar English 85
5) Hari History 89
我们将使用 AWK 脚本来显示输出文件中的内容,同时输出表头信息,最后一行输出文件行数
[root@entos7 awk_test]# awk 'BEGIN{printf "Sr No\tName\tSub\tMarks\n"} {print $0} END{print "Total Line="NR}' marks.txt
Sr No Name Sub Marks
1) Amit Physics 80
2) Rahul Maths 90
3) Shyam Biology 87
4) Kedar English 85
5) Hari History 89
Total Line=5
程序启动时,AWK 在开始块中输出表头信息。在主体块中,AWK 每读入一行就将读入的内容输出至标准输出流中,一直到整个文件被全部读入为止。最后一行结束后,执行END语句块,打印文件行数。
3 AWK内置变量
AWK 提供了一些内置变量。 它们在你写 AWK 脚本的时候起着很重要的作用。 这一章节中将会展示如何使用这些内置变量。
内置变量列表如下:
| 变量名 | 说明 |
|---|---|
| ARGC | 表示在命令行提供的参数的个数。 |
| ARGV | 该变量为存储命令行输入参数的数组。数组的有效索引是从 0 到 ARGC-1 |
| CONVFMT | 此变量表示数据转换为字符串的格式,其默认值为 %.6g。 |
| ENVIRON | 此变量是与环境变量相关的关联数组变量 |
| FILENAME | 此变量表示当前文件名称 |
| NF | 此变量表示当前输入记录的列数. |
| NR | 此变量表示当前记录的行号。(译注:该变量类似一个计数器,统计记录的数量) |
| FNR | 该变量与 NR 类似,不过它是相对于当前文件而言的。此变量在处理多个文件输入时有重要的作用。每当从新的文件中读入时 FNR 都会被重新设置为 0 |
| FS | 此变量表示输入的数据域之间的分隔符,其默认值是空格。 你可以使用 -F 命令行选项改变它的默认值 |
| RS | 此变量表示输入记录的分割符,其默认值为换行符 |
| OFS | 此变量表示输出域之间的分割符,其默认为空格 |
| ORS | 此变量表示输出记录(行)之间的分割符,其默认值是换行符 |
$0 |
当前处理行的整行内容 |
$n |
当前处理行的第n个字段 |
3.1 ARGC
ARGC表示在命令行提供的参数个数
[root@entos7 awk_test]# awk 'BEGIN{print "Aaguments =", ARGC}' one two three four
Aaguments = 5
这里因为还有个默认参数awk,所有计算出来的参数为5个:awk one two three four
3.2 ARGV
这个变量是存储命令行输入参数的数组。数组的有效索引是从 0 到 ARGC-1。
[root@entos7 awk_test]# awk 'BEGIN{ for(i=0;i<ARGC;i++){print i,ARGV[i]} }' one two three four
0 awk
1 one
2 two
3 three
4 four
3.3 CONVFMT
此变量表示数据转换为字符串的格式,其默认值为 %.6g。
[root@entos7 awk_test]# awk 'BEGIN { print "Conversion Format =", CONVFMT }'
Conversion Format = %.6g
3.4 ENVIRON
此变量是与环境变量相关的关联数组变量。
[root@entos7 awk_test]# awk 'BEGIN {print ENVIRON["SHELL"],ENVIRON["USER"]}'
/bin/bash root
3.5 FILENAME
此变量表示当前文件名
# FILENAME在开始块中未定义,因此在BEGIN块中打印该参数为空
[root@entos7 awk_test]# awk 'BEGIN {print FILENAME}' marks.txt
[root@entos7 awk_test]# awk 'END {print FILENAME}' marks.txt
marks.txt
值得注意的是在开始块中FILENAME是未定义的。
3.6 NF
此变量表示当前输入记录的列数。例如,下面这个例子只输出超过两个列的行:
[root@entos7 awk_test]# echo -e 'One\nOne Two\nOne Two Three\nOne Two Three Four'|awk 'NF > 2 {print}'
One Two Three
One Two Three Four
3.7 NR(number of row)
此变量表示当前记录的行号。(译注:该变量类似一个计数器,统计记录的数量)。下面例子会输出读入的前三行(NR<3)
[root@entos7 awk_test]# echo -e 'One\nOne Two\nOne Two Three\nOne Two Three Four'|awk 'NR < 3 {print}'
One
One Two
3.8 FNR
该变量与 NR 类似,不过它是相对于当前文件而言的。此变量在处理多个文件输入时有重要的作用。每当从新的文件中读入时 FNR 都会被重新设置为 0。
3.9 FS
此变量表示输入的数据域之间的分隔符,其默认值是空格。 你可以使用 -F 命令行选项改变它的默认值。
# 使用-F指定分隔符
[root@entos7 awk_test]# echo -e 'onegoodtwobadthreegoodfourbadfive'|awk -F 'good|bad' '{printf("%10s %10s\n",$1,$2)}'
one two
# 使用FS制定分隔符
[root@entos7 awk_test]# echo -e 'onegoodtwobadthreegoodfourbadfive'|awk -v FS='good|bad' '{printf("%10s %10s\n",$1,$2)}'
one two
3.10 RS(row separate)
此变量表示输入记录的分割符,其默认值为换行符。
[root@entos7 awk_test]# awk 'BEGIN {printf("RS=%10s",RS)}'
RS=
3.11 OFS
此变量表示输出的域(列)之间的分隔符,默认为空格
[root@entos7 awk_test]# awk 'BEGIN {printf("OFS=%-10s\n",OFS)}'
OFS=
3.12 ORS
此变量表示输出记录(行)之间的分割符,其默认值是换行符
3.13 $0
当前处理行的整行内容
3.14 $n
当前处理行的第n个字段(第n列)
awk '{print $1}' filename
4、运算符
与其它编程语言一样,AWK 也提供了大量的操作符。
4.1 算术运算符
`+加 -减 *乘 /除 %求余
详见以下示例
[root@entos7 awk_test]# awk 'BEGIN { a = 50;b = 20; printf("%d + %d = %d\n", a,b,a + b)}'
50 + 20 = 70 # + 求和
[root@entos7 awk_test]# awk 'BEGIN { a = 50;b = 20; printf("%d - %d = %d\n", a,b,a - b)}'
50 - 20 = 30 # - 求差
[root@entos7 awk_test]# awk 'BEGIN { a = 50;b = 20; printf("%d * %d = %d\n", a,b,a * b)}'
50 * 20 = 1000 # 求乘积
[root@entos7 awk_test]# awk 'BEGIN { a = 50;b = 20; printf("%d / %d = %d\n", a,b,a / b)}'
50 / 20 = 2 # 求除
[root@entos7 awk_test]# awk 'BEGIN { a = 50;b = 20; printf("%d %% %d = %d\n",a,b,a % b)}'
50 % 20 = 10 # 求余
[root@entos7 awk_test]# awk 'BEGIN {a = 2;b = 4; printf("a = %d, b = %d, a \^ b = %d\n", a, b, a ^ b)}'
a = 2, b = 4, a ^ b = 16 # 求乘方
[root@entos7 awk_test]# awk 'BEGIN {a = 2;b = 4; printf("a = %d, b = %d, a ** b = %d\n", a, b, a ^ b)}'
a = 2, b = 4, a ** b = 16 # 求乘方
4.2 增加运算符
自增自减与C语言一致++自增 --自减
[root@entos7 awk_test]# awk 'BEGIN {a = 10;b = ++a; printf("a = %d, b = %d\n", a, b)}'
a = 11, b = 11
[root@entos7 awk_test]# awk 'BEGIN {a = 10;b = --a; printf("a = %d, b = %d\n", a, b)}'
a = 9, b = 9
[root@entos7 awk_test]# awk 'BEGIN {a = 10; b = a++; printf("a = %d , b = %d\n", a, b)}'
a = 11 , b = 10
[root@entos7 awk_test]# awk 'BEGIN {a = 10; b = a--; printf("a = %d , b = %d\n", a, b)}'
a = 9 , b = 10
4.3 赋值运算符
赋值运算符包括: = 赋值运算符 += -= *= \= %= ^= **= 其中^=和**=一样
[root@entos7 awk_test]# awk 'BEGIN { name = "Jerry";printf("name = %s\n", name) }'
name = Jerry
[root@entos7 awk_test]# awk 'BEGIN { a = 10; a += 10; printf("a = %d\n", a) }'
a = 20
[root@entos7 awk_test]# awk 'BEGIN { a = 10; a -= 10; printf("a = %d\n", b) }'
a = 0
[root@entos7 awk_test]# awk 'BEGIN { a = 10; a *= 2; printf("a = %d\n", a)}'
a = 20
[root@entos7 awk_test]# awk 'BEGIN { a = 10; a /= 2; printf("a = %d\n", a)}'
a = 5
[root@entos7 awk_test]# awk 'BEGIN { a = 2; a ^= 4; printf("a = %d\n", a)}'
a = 16
[root@entos7 awk_test]# awk 'BEGIN { a = 2; a **= 4; printf("a = %d\n", a)}'
a = 16
4.4 关系操作符
关系操作符如下:
==等于,若两边相等,返回True,否则False!=不等于,若两边不相等,返回True,否则False<,<=小于,小于等于。若左侧小于(小于等于)右侧,返回Ture,否则False>,>=大于,大于等于。若左侧大于(大于等于)右侧,返回Ture,否则False
[root@entos7 awk_test]# awk 'BEGIN { a = 2; b = 4; if( a == b) printf("a == b\n");else printf("a != b\n") }'
a != b
[root@entos7 awk_test]# awk 'BEGIN { a = 2; b = 2; if( a == b) printf("a == b\n");else printf("a != b\n") }'
a == b
[root@entos7 awk_test]# awk 'BEGIN { a = 2; b = 4; if( a > b) printf("a > b\n"); else printf("a <= b\n")}'
a <= b
[root@entos7 awk_test]# awk 'BEGIN { a = 4; b = 2; if( a < b) printf("a < b\n"); else printf("a >= b\n")}'
a >= b
4.5 逻辑操作符
&&且,a && b。若a,b都为true,则true。a,b中有一个为false,则false。||或,a || b。a,b中一个为true,则true。a,b两个都为false,则false。!非。!a。 a为True,则为false。a为false,则为true。
[root@entos7 awk_test]# awk 'BEGIN { num = 5; if( num >= 0 && num <=7) printf("%d is in octal format\n", num)}'
5 is in octal format
[root@entos7 awk_test]# awk 'BEGIN { ch = " "; if( ch == " " || ch == "\t") printf("ch is whitespace\n")}'
ch is whitespace
[root@entos7 awk_test]# awk 'BEGIN { name = "";if( !length(name) ) printf("name is empty string.\n")}'
name is empty string.
4.6 一元操作符
+ 取正值 -取负值
[root@entos7 awk_test]# awk 'BEGIN { a = -10; a = -a; printf("a = %d\n", a)}'
a = 10
[root@entos7 awk_test]# awk 'BEGIN { a = -10; a = +a; printf("a = %d\n", a)}'
a = -10
4.7 字符串连接符
awk 'BEGIN {str1="Hello,"; str2 = "World!"; str3 = str1 str2; printf("str3 is \"%s\"\n", str3)}'
str3 is "Hello,World!"
4.9 正则表达式操作符
正则表达式操作符使用 ~ 和 !~ 分别代表匹配和不匹配
[root@entos7 awk_test]# awk '$0 ~ 9' marks.txt
2) Rahul Maths 90
3) Hari History 89
[root@entos7 awk_test]# awk '$0 !~ 9' marks.txt
4) Amit Physics 80
5) Shyam Biology 87
6) Kedar English 85
# 匹配正则表达式需要在表达式前后添加反斜线,与js类似
$ tail -n 40 /var/log/nginx/access.log | awk '$0 ~ /ip\[127\.0\.0\.1\]/'
5、awk正则表达式
5.1 点(dot)
点字符(.)可以匹配除了行结束字符的所有字符,只能出现一次,且必须出现一次。比如下面的便子就可以匹配 fin, fun, fan 等等。
echo -e "cat\nbat\nfun\nfin\nfn\nfaan" | awk '/f.n/'
fun
fin
5.2 行开始
行开始符(^)匹配一行的开始。下面的示例将输出所有以字符串 The 开始的行
echo -e "This\nThat\nThere\nTheir\nthese" | awk '/^The/'
There
Their
5.3 行结束
行结束符($)匹配一行的结束。下面的例子中将输出所有以字符 n 结束的行
echo -e "knife\nknow\nfun\nfin\nfan\nnine" | awk '/n$/'
fun
fin
fan
5.4 匹配字符集
匹配字符集用于匹配集合(由方括号表示)中的一个字符。如下例子中,匹配 Call 与 Tall 而不会匹配 Ball
echo -e "Call\nTall\nBall" | awk '/[CT]all/'
Call
Tall
5.5 排除集
正则匹配时会排除集合中的字符。如下例子中只会输出 Ball。
echo -e "Call\nTall\nBall" | awk '/[^CT]all/'
Ball
5.6 或选择
竖线(|)允许正则表达式实现逻辑或运算. 下面例子将会输出 Ball 与 Call
echo -e "Call\nTall\nBall\nSmall\nShall" | awk '/Call|Ball/'
Call
Ball
5.7 最多出现一次
该符号( ?)前面的单个字符出现0次或者出现一次。如下示例匹配 Colour 与 Color。 使用 ? 使得 u 变成了可选字符 。
echo -e "Colour\nColor" | awk '/Colou?r/'
Colour
Color
5.8 出现零次或多次
该符号(*) 允许其前面的单个字符出现多次或者0次。如下示例将匹配 ca,cat, catt 等等。
echo -e "ca\ncat\ncatt" | awk '/cat*/'
ca
cat
catt
5.9 出现一次或多次
该符号(+)使得其前的字符出现一次或者多次。下面的例子会匹配一个 2 或者多个连续的 2
echo -e "111\n22\n123\n234\n456\n222" | awk '/2+/'
22
123
234
222
5.10 分组
括号用于分组而字符 | 用于提供多种选择。如下的正则表达式会匹配所有包含 Apple Juice 或 Aplle Cake 的行。
与前面 [] 区别在于,[]是取单个字符,而这里是取一个字符串
echo -e "Apple Juice\nApple Pie\nApple Tart\nApple Cake" | awk '/Apple (Juice|Cake)/'
Apple Juice
Apple Cake
6、控制语句
6.1 IF语句
条件语句测试条件,然后根据条件执行相应的动作。条件语句语法:
if (condition)
action
也可以使用花括号{}来执行一组操作
if (condition)
{
action-1
action-2
action-3
.
.
.
action-n
}
下面的例子判断数字是奇数还是偶数:
[root@entos7 awk_test]# seq 10 | awk '{if($1 % 2 == 0) printf("%d is even number.\n",$1)}'
2 is even number.
4 is even number.
6 is even number.
8 is even number.
10 is even number.
6.2 IF_ELSE语句
if-else语句中允许在条件为假时执行另外一组的动作。下面为 if-else 的语法格式:
if (condition)
action-1
else
action-2
其中,条件为真时执行 action-1,条件为假时执行 action-2。下面是使用该语句判断数字是否为偶数的例子:
[root@entos7 awk_test]# seq 10 | awk '{if($1 % 2 == 0) printf("%d is even number.\n",$1); else printf("%d is odd num.\n", $1)}'
1 is odd num.
2 is even number.
3 is odd num.
4 is even number.
5 is odd num.
6 is even number.
7 is odd num.
8 is even number.
9 is odd num.
10 is even number.
6.3 if-elseif梯
我们可以很轻松地使用多个 if-else 语句构造 if-else-if 梯从而实现多个条件的判断。示例如下:
awk 'BEGIN { a=30; \
if (a==10) print "a = 10";\
else if (a == 20) print "a = 20"; \
else if (a == 30) print "a = 30"; \
}'
a = 30
7、循环
7.1 For循环
语法如下:
for (initialisation; condition; increment/decrement)
action
for 语句首先执行初始化动作( initialisation ),然后再检查条件( condition )。如果条件为真,则执行动作( action ),然后执行递增( increment )或者递减( decrement )操作。只要条件为真循环就会一直执行。每次循环结束都会进条件检查,若条件为假则结束 循环。下面的例子使用 For 循环输出数字 1 至 5:
[root@entos7 awk_test]# awk 'BEGIN{ for(n=1; n<6; n++) printf("%d\n", n) }'
1
2
3
4
5
7.2 while循环
While 循环会一直执行动作直到逻辑条件为假为止。其使用方法如下:
while (condition)
action
AWK 首先检查条件是否为真,若条件为真则执行动作。此过程一直重复直到条件为假时,则停止。下面是使用 While 循环输出数字 1 到 5 的例子
[root@entos7 awk_test]# awk 'BEGIN{ n=1; while(n<6){ printf("%d\n",n);n++ } }'
1
2
3
4
5
6.3 Do-while
Do-While 循环与 While 循环相似,但是 Do-While 的条件测试放到了循环的尾部。下面是 do-while 的语法
do
action
while (condition)
在 do-while 循环中,无论条件是真是假,循环语句至少执行一次,执行后检查条件真假。下面是使用 do-While 循环输出数字 1 到 5 的例子:
[root@entos7 awk_test]# awk 'BEGIN { n=1; do {printf("%d\n",n); ++n} while(n<6) }'
1
2
3
4
5
6.4 break
顾名思义,break 用以结束循环过程(break只跳出当前的循环,如果想要进行多层循环操作,则需要在后面加数字,如 break 2)。在下面的示例子中,当计算的和大于 50 的时候使用 break 结束循环过程:
[root@entos7 awk_test]# awk 'BEGIN { sum = 0;for(i=0; i<=20; i++){ sum = sum + i; if(sum < 50) printf("sum is %d\n",sum); else break;} }'
sum is 0
sum is 1
sum is 3
sum is 6
sum is 10
sum is 15
sum is 21
sum is 28
sum is 36
sum is 45
7.5 continue
Continue 语句用于在循环体内部结束本次循环,从而直接进入下一次循环迭代。(coninue只结束当前的循环,如果想要结束多层循环操作,则需要在后面加数字,如 continue 2)当我们希望跳过循环中某处数据处理时就会用到 Continue。下面的例子输出 1 到 20 之间的偶数:
[root@entos7 awk_test]# awk 'BEGIN{ for(i=0; i<20; i++){ if(i % 2 == 0) printf("%d\n", i); else continue} }'
0
2
4
6
8
10
12
14
16
18
7.6 exit
Exit 用于结束脚本程序的执行。该函数接受一个整数作为参数表示 AWK 进程结束状态。 如果没有提供该参数,其默认状态为 0 。下面例子中当和大于 50 时结束 AWK 程序。
[jerry]$ awk 'BEGIN {
sum = 0; for (i = 0; i < 20; ++i) {
sum += i; if (sum > 50) exit(10); else print "Sum =", sum
}
}'
Sum = 0
Sum = 1
Sum = 3
Sum = 6
Sum = 10
Sum = 15
Sum = 21
Sum = 28
Sum = 36
Sum = 45
让我们检查一下脚本执行后的返回状态:
echo $?
10
8 awk数组相关
8.1 基本概念
awk中数组的下标可以是数字和字母(类似pyhton中的字典),数组的下标通常被称为关键字(key)。值和关键字都存储在内部的一张针对key/value应用hash的表格里。由于hash不是顺序存储,因此在显示数组内容时会发现,它们并不是按照你预料的顺序显示出来的。数组和变量一样,都是在使用时自动创建的,awk也同样会自动判断其存储的是数字还是字符串。一般而言,awk中的数组用来从记录中收集信息,可以用于计算总和、统计单词以及跟踪模板被匹配的次数等等。
8.2 数组创建及赋值
创建数组的方式非常简单,直接为变量赋值即可
[root@entos7 awk_test]# awk 'BEGIN { \
arr[0] = 1; arr[1] = 2; arr[2] = 3;
for (i = 0; i < 3; i++) { printf("a[%d] is %d\n", i, arr[i]) }
}'
a[0] is 1
a[1] is 2
a[2] is 3
[root@entos7 awk_test]# vim dict_test.awk
#!/usr/bin/awk -f
BEGIN {
fruits["mango"] = "orange";
fruits["orange"] = "orange";
printf("mango's color is %s\n", fruits["mango"]);
printf("orange's color is %s\n", fruits["orange"]);
}
[sc_test@vlogin02 ~]$ ./dict_test.awk
mango's color is orange
orange's color is orange
8.3 删除数组元素
使用delete删除数组元素
[root@entos7 awk_test]# vim dict_delete.awk
#!/usr/bin/awk -f
BEGIN{
fruits["mango"] = "yellow";
fruits["apple"] = "red";
fruits["orange"] = "orange"; # 删除orange数组
delete fruits["orange"];
for(i in fruits) {
printf( "%s's color is %s\n", i, fruits[i]);
}
}
[root@entos7 awk_test]# ./dict_delete.awk
mango's color is yellow
apple's color is red
# 数组元素 fruits["orange"]已被删除
8.4 遍历数组
使用方法:
for(变量 in 数组名){
动作指令序列
}
示例
[root@entos7 awk_test]# vim dict_allaccess.awk
#!/usr/bin/awk -f
BEGIN{
fruits["mango"] = "yellow";
fruits["apple"] = "red";
fruits["orange"] = "orange";
for(i in fruits) {
printf( "%s's color is %s\n", i, fruits[i]);
}
}
[root@entos7 awk_test]# ./dict_allaccess.awk
orange's color is orange
mango's color is yellow
apple's color is red
8.5 多维数组
awk不支持多维数组,但是可以通过指定key值进行模仿
例如一个3*3的数组
100 200 300
400 500 600
700 800 900
可以通过以下方式进行模仿
[root@entos7 awk_test]# vim Multidimen.awk
#!/usr/bin/awk -f
BEGIN {
array["0,0"] = 100;
array["0,1"] = 200;
array["0,2"] = 300;
array["1,0"] = 400;
array["1,1"] = 500;
array["1,2"] = 600;
# print array elements
print "array[0,0] = " array["0,0"];
print "array[0,1] = " array["0,1"];
print "array[0,2] = " array["0,2"];
print "array[1,0] = " array["1,0"];
print "array[1,1] = " array["1,1"];
print "array[1,2] = " array["1,2"];
}
[root@entos7 awk_test]# chmod +x Multidimen.awk
[root@entos7 awk_test]# ./Multidimen.awk
array[0,0] = 100
array[0,1] = 200
array[0,2] = 300
array[1,0] = 400
array[1,1] = 500
array[1,2] = 600
9、awk脚本文件
9.1 基本信息
| 类别 | 内容 |
|---|---|
| shebang | 使用#!/usr/bin/awk -f声明。awk路径可以通过which awk确认 |
| 脚本结构 | 包含BEGIN,BODY主处理逻辑,END三个部分 |
| 执行方式 | 可以直接运行(需要可执行权限)或通过awk -f script.awk执行 |
| 文件权限 | 需要赋予脚本可执行权限:chmod +x script.awk |
| 输入涟源 | 支持标准输入、管道输入和文件输入 |
| 跨平台兼容性 | 在Ubuntu、Cetnos、EulerOS上行为一致 |
9.2 示例
示例一:打印信息
[root@entos7 awk_test]# vim hello.awk
#!/usr/bin/awk -f
BEGIN {
print "Hello World from awk!";
}
[root@entos7 awk_test]# chmod +x hello.awk
[root@entos7 awk_test]# ./hello.awk
Hello World from awk!
示例二:打印/etc/passwd文件中41行至55开始的用户名,用户ID,组ID,用户家目录,bash
[root@entos7 awk_test]# vim user_info.awk
#!/usr/bin/awk -f
BEGIN {
FS = ":";
printf("用户名\t用户ID\t用户组ID\t用户家目录\t用户shell\n")
}
# BODY主逻辑部分
{
if( NR > 40 && NR < 56 ) printf("%s\t%s\t%s\t%s\t%s\n", $1, $3, $4, $6, $7)
}
END {
printf("用户作数为:%10d\n", NR)
}
[root@entos7 awk_test]# chmod +x user_info.awk
[root@entos7 awk_test]# ./user_info.awk /etc/passwd
用户名 用户ID 用户组ID 用户家目录 用户shell
sssd 989 983 / /sbin/nologin
dirsrv 988 982 /usr/share/dirsrv /sbin/nologin
setroubleshoot 987 981 /var/lib/setroubleshoot /sbin/nologin
saned 986 980 /usr/share/sane /sbin/nologin
hsqldb 96 96 /var/lib/hsqldb /sbin/nologin
tomcat 53 53 /usr/share/tomcat /sbin/nologin
pkiuser 17 17 /usr/share/pki /sbin/nologin
gdm 42 42 /var/lib/gdm /sbin/nologin
gnome-initial-setup 985 979 /run/gnome-initial-setup/ /sbin/nologin
pcp 984 978 /var/lib/pcp /sbin/nologin
kdcproxy 983 977 / /sbin/nologin
ipaapi 982 976 / /sbin/nologin
sshd 74 74 /var/empty/sshd /sbin/nologin
avahi 70 70 /var/run/avahi-daemon /sbin/nologin
postfix 89 89 /var/spool/postfix /sbin/nologin
用户作数为: 58
本文主要参考了一下博客,再次特别感谢
浙公网安备 33010602011771号