第一部分:Linux命令行
《Linux命令行与shell脚本编程大全》 第一章:初识Linux shell
《Linux命令行与shell脚本编程大全》 第二章:走进shell
《Linux命令行与shell脚本编程大全》 第三章:基本的bash shell命令
《Linux命令行与shell脚本编程大全》 第四章:更多的bash shell命令
《Linux命令行与shell脚本编程大全》 第五章:使用Linux环境变量
《Linux命令行与shell脚本编程大全》 第六章:理解Linux文件权限
《Linux命令行与shell脚本编程大全》 第七章:管理文件系统
《Linux命令行与shell脚本编程大全》 第八章:安装软件程序
《Linux命令行与shell脚本编程大全》 第九章:使用编辑器
第二部分:shell脚本编程基础
《Linux命令行与shell脚本编程大全》 第十章:构建基本脚本
《Linux命令行与shell脚本编程大全》 第十一章:使用结构化命令
《Linux命令行与shell脚本编程大全》 第十二章:更多的结构化命令
《Linux命令行与shell脚本编程大全》 第十三章:处理用户输入
《Linux命令行与shell脚本编程大全》 第十四章:呈现数据
《Linux命令行与shell脚本编程大全》 第十五章:控制脚本
第三部分:高级shell编程
《Linux命令行与shell脚本编程大全》 第十六章:创建函数
《Linux命令行与shell脚本编程大全》 第十七章:图形化桌面上的脚本编程
《Linux命令行与shell脚本编程大全》 第十八章:初识sed和gawk
《Linux命令行与shell脚本编程大全》 第十九章:正则表达式
《Linux命令行与shell脚本编程大全》 第二十章:sed进阶
《Linux命令行与shell脚本编程大全》 第二十一章:gawk进阶
《Linux命令行与shell脚本编程大全》 第二十二章:使用其他shell
第四部分:高级shell脚本编程主题
《Linux命令行与shell脚本编程大全》 第二十三章:使用数据库
《Linux命令行与shell脚本编程大全》 第二十四章:使用Web
《Linux命令行与shell脚本编程大全》 第二十五章:使用E-mail
《Linux命令行与shell脚本编程大全》 第二十六章:编写脚本实用工具
《Linux命令行与shell脚本编程大全》 第二十七章:shell脚本编程进阶
第二十一章:gawk进阶
使用变量
gawk支持两种类型的变量:
内建变量
自定义变量
内建变量
字段和数据行分割符变量
使用美元符号($)和数据字段在数据行中位置对应的数值来引用该数据行中的字段。
比如,要引用数据行中的第二个字段就使用$2
gawk数据字段和数据行变量
变量 | 描述 |
FIELDWIDTHS | 由空格分隔开的定义了每个数据字段确切宽度的一列数字 |
FS | 输入字段分割符 |
RS | 输入数据行分割符 |
OFS | 输入字段分隔符 |
ORS | 输入数据行分隔符 |
OFS默认值为空格
$ cat column_data.txt 1987-06-05 $ gawk 'BEGIN{FS="-"} {print $1,$2,$3}' column_data.txt 1987 06 05 $ gawk 'BEGIN{FS="-";OFS=":"} {print $1,$2,$3}' column_data.txt 1987:06:05
一旦设置了FIELDWIDTHS,FS就会失效
一旦设置了FIELDWIDTHS值,就不可再更改
下面演示一下RS
假设我们有一份联系人名单,每个联系人之间用空行分割,格式如下
$ cat contacts Name1 Addr1 ZipCode1 Tele1 Name2 Addr2 ZipCode2 Tele2 Name3 Addr3 ZipCode3 Tele3
下面我们想读取姓名与电话。
默认情况下,gawk以换行符为行分隔符,这里我们可以使用空作为行分隔符。这样做的结果就是,使得每一个联系人作为单独的“一行”。然后我们再把字段分隔符设置为换行符,这样就可以提取我们所需要的内容了。
$ gawk 'BEGIN{FS="\n";RS=""} {print $1,$4}' contacts Name1 Tele1 Name2 Tele2 Name3 Tele3
数据变量
变量 | 描述 |
ARGC | 当前命令行参数个数 |
ARGIND | 当前文件在ARGV中的位置 |
ARGV | 包含命令行参数的数组 |
CONVFMT | 数字的转换格式(参见print语句);默认值为%.6 g |
ENVIRON | 当前shell环境变量及其值组成的关联数组 |
ERRNO | 当读取或关闭输入文件发生错误时的系统错误号 |
FILENAME | 用作gawk输入数据的数据文件的文件名 |
FNR | 当前数据文件中的数据行数 |
IGNORECASE | 设成非0值时,忽略gawk命令中出现的字符串的字符大小写 |
NF | 数据文件中的字段总数 |
NR | 已处理的输入数据行数目 |
OFMT | 数字的输出格式;默认值为%.6 g |
RLENGTH | 由match函数所匹配的子字符串的长度 |
RSTART | 由match函数所匹配的子字符串的起始位置 |
在gawk中引用gawk变量的时候,不需要美元符号
$ gawk 'BEGIN{print ARGC,ARGV[0],ARGV[1]}' contacts 2 gawk contacts
上面命令中共两个参数,gawk以及contacts
注意:gawk后的脚本不算参数
我们可以通过如下方式获取系统环境变量,既而在gawk中使用。
$ gawk 'BEGIN{print ENVIRON["HOME"]}' /home/su1216
我们可以通过如下方式来指定最后一个字段
$ gawk 'BEGIN{FS=":"; OFS=":"} {print $1,$NF}' /etc/passwd root:/bin/bash daemon:/bin/sh bin:/bin/sh sys:/bin/sh ......
注意:这里gawk先把NF计算出来,然后再执行$number,而不是像shell中把$NF视为对NF变量的引用。
下面看一下FNR与NR的区别
$ gawk 'BEGIN{FS="\n";RS=""} {print $1,"FNR="FNR, "NR="NR}' contacts contacts Name1 FNR=1 NR=1 Name2 FNR=2 NR=2 Name3 FNR=3 NR=3 Name1 FNR=1 NR=4 Name2 FNR=2 NR=5 Name3 FNR=3 NR=6
如果只使用一个数据文件作为输入,那么FNR与NR则一致。
处理第二个文件时,FNR变量被重置。
自定义变量
在脚本中给变量赋值
同shell中的变量赋值类似:
$ gawk ' > BEGIN{ > test="This is a test." > print test > test="Test again." > print test > }' This is a test. Test again.
还可以在其中直接进行数学运算
$ gawk ' BEGIN{ x=1 print "x="x x=(x+1)**2 print "x="x }' x=1 x=4
可以直接进行求余(%)和方幂(**或者^)运算
在命令行上给变量赋值
可以在gawk脚本之外给gawk中变量赋值
$ cat gawk_script BEGIN{FS=":"}{print $n}
上面是一个普通的gawk脚本,其中使用了变量n,但是并没有为其进行初始化。
$ gawk -f gawk_script n=1 /etc/passwd root daemon bin ......
但是这个变量在BEGIN中是无效的,如果想在BEGIN中生效,需要使用-v选项。
$ gawk -v n=1 -f gawk_script /etc/passwd
处理数组
gawk使用关联数组来提供数组功能,它的索引可以是任意文本字符串。
定义数组变量
$ gawk ' > BEGIN{test["a"]="a" > print test["a"] > }' a
遍历数组变量
可以使用for语句:
for (var in array) { statements }
例如:
$ gawk ' > BEGIN { > test["a"]="a1" > test["b"]="b2" > test["c"]="c3" > for (var in test) > { > print var,test[var] > } > }' a a1 b b2 c c3
删除数组变量
delete array[index]
$ gawk ' > BEGIN { > test["a"]="a1" > test["b"]="b2" > test["c"]="c3" > delete test["b"] > for (var in test) > { > print var,test[var] > } > }' a a1 c c3
使用模式
BEGIN和END是用来在读取数据流之前或之后执行命令的特殊模式。
正则表达式
正则表达式必须出现在它要控制的程序脚本的左花括号前:
$ gawk '/Name[0-9]/{print $0}' contacts Name1 Name2 Name3
匹配操作符(matching operator)
匹配操作符允许将正则表达式限定在数据行中的特定数据字段。匹配操作符是波浪线(~)。需要一起指定匹配操作符、数据字段变量以及正则表达式:
$ gawk 'BEGIN{FS=":"} $1 ~ /sys/{print $0}' /etc/passwd sys:x:3:3:sys:/dev:/bin/sh syslog:x:101:103::/home/syslog:/bin/false
这里$1表示第一个字段,也就是说,打印出第一个字段中含有sys字样的行
可以使用!~来过滤没有满足正则表达式的字符串。
$ gawk 'BEGIN{FS=":"} $1 !~ /[aeiou]/{print $0}' /etc/passwd sys:x:3:3:sys:/dev:/bin/sh sync:x:4:65534:sync:/bin:/bin/sync lp:x:7:7:lp:/var/spool/lpd:/bin/sh gdm:x:113:120:Gnome Display Manager:/var/lib/gdm:/bin/false sshd:x:115:65534::/var/run/sshd:/usr/sbin/nologin
数学表达式
可以使用下面几种形式:
x == y
x <= y
x < y
x > y
x >= y
这里不仅局限于数值比较,也可以作用在字符串上。
$ gawk 'BEGIN{FS=":"} $4 == 0{print $0}' /etc/passwd root:x:0:0:root:/root:/bin/bash $ gawk 'BEGIN{FS=":"} $1 == "sys"{print $0}' /etc/passwd sys:x:3:3:sys:/dev:/bin/sh
结构化命令
if语句
语句格式:
if(condition) statement if(condition) statement if(condition){ statements } if(condition){ statements }else{ statements } if(condition) statement1; else statement2
while语句
语句格式:
while(condition){ statements }
do-while语句
语句格式:
do { statements } while (condition)
for语句
gawk支持C风格的for循环
语句格式:
for(variable assignment; condition; iteration process)
格式化打印
printf命令格式:
printf "format string", var1, var2 ...
gawk程序会将每个格式化指定符作为命令中列出的每个变量的占位符使用。第一个格式化指定符会匹配列出的第一个变量,第二个会匹配第二个变量,依此类推。
格式化指定符采用如下格式:
%[modifier]control-letter
其中control-letter指明显示什么类型数据值的单字符码,而modifier定义了另一个可选的格式化特性。
格式化指定符的控制字母
控制字母 | 描述 |
c | 将一个数作为ASCII字符显示 |
d | 显示一个整数值 |
i | 显示一个整数值(跟d一样) |
e | 用科学记数法显示一个数 |
f | 显示一个浮点值 |
g | 用科学记数法或浮点数中较短的显示 |
o | 显示一个八进制值 |
s | 显示一个文本字符串 |
x | 显示一个十六进制值 |
X | 显示一个十六进制值,但用大写字符A-F |
除了控制字母外,还有3种修饰符可以用来进一步控制输出。
width:指定了输出字段最小宽度的数字值。如果短于这个值,printf会向右对齐,并用空格来填充这段空间。如果输出比指定的宽度还要长,它就覆盖width值。
prec:指定了浮点数中小数点后面位数的数字值,或者文本字符串中显示的最大字符数。
-(减号):向格式化空间中放入数据时采用左对齐。
printf每打印一次,不会自动换行。
$ cat numbers 1 2 3 123 456 789 172 245 946 $ gawk '{ > total = 0 > for (i = 1; i < 4; i++) > { > total += $i > } > avg = total/3 > printf "Average: %5.1f\n",avg > }' numbers Average: 2.0 Average: 456.0 Average: 454.3
上面指定了显示浮点数,输出最小宽度是5,保留小数后一位,右对齐。
内建函数
gawk数学函数
函数 | 描述 |
atan2(x,y) | x/y的反正切,x和y以弧度为单位 |
cos(x) | x的余弦,x以弧度为单位 |
exp(x) | x的指数函数 |
int(x) | x的整数部分,取靠近0一侧的值 |
log(x) | x的自然对数 |
rand() | 比0大比1小的随机浮点值 |
sin(x) | x的正弦,x以弧度为单位 |
sqrt(x) | x的平方根 |
srand(x) | 为计算随机数指定一个种子值 |
除了标准函数外,gawk还支持一些按位操作数据的函数
and(v1, v2):v1和v2的按位与运算
compl(val):val的补运算
lshift(val, count):将值val左移count位
or(v1, v2):v1和v2的按位或运算
rshift(val, count):将值val右移count位
xor(v1, v2):执行值v1和v2的按位异或运算
gawk字符串函数
函数 | 描述 |
asort(s [, d]) | 将数组s按数据元素值排序。索引值会被替换成表示新的排序顺序的连续数字。如果指定了d,则排序后的数组回存储在数组d中 |
asorti(s [, d]) | 将数组s按索引值排序。生成的数组会将索引值作为数据元素值,用连续数组索引来表明排序顺序。如果指定了d,排序后的数组回存储在数组d中 |
gensub(r, s, h [, t]) | 查找变量$0或目标字符串t(如果提供了的话)来匹配正则表达式r。如果h是一个以g或者G开头的字符串,就用s替换掉匹配的文本。如果h是一个数字,它表示要替换掉第几处r匹配的地方 |
gsub(r, s, [, t]) | 查找变量$0或目标字符串t(如果提供了的话)来匹配正则表达式r。如果找到了,就全部替换成字符串s |
index(s, t) | 返回字符串t在字符串s中的索引值,如果没找到的话,返回0 |
length([s]) | 返回字符串s的长度,如果没有指定的话,返回$0的长度 |
match(s, r [, a]) | 返回字符串s中正则表达式r出现位置的索引。如果指定了数组a,它会存储s中匹配正则表达式的那部分 |
split(s, a [, r]) | 将s用FS字符或正则表达式r(如果指定了的话),分开放到数组a中。返回字段的总数 |
sprintf(format, variables) | 用提供的format和variables返回一个类似于printf输出的字符串 |
sub(r, s [, t]) | 在变量$0或目标字符串t中查找正则表达式r的匹配。如果找到了,就用字符串s替换掉第一处匹配 |
substr(s, i [, n]) | 返回s中从索引值i开始的n个字符组成的子字符串。如果未提供n,则返回s剩下的部分 |
tolower(s) | 将s的所有字符转换成小写 |
toupper(s) | 将s的所有字符转换成大写 |
gawk的时间函数
函数 | 描述 |
mktime(datespec) | 将一个YYYY MM DD HH MM SS [DST]格式置顶的日期转换彻骨时间戳(时间戳指:自1970-01-01 00:00:00 UTC到现在,以秒为单位的计数,通常称epoch time) |
strftime(format [, timestamp]) | 将当前时间的时间戳huotimestamp(如果提供了的话)转化成用shell函数格式date()的格式化日期 |
systime() | 返回当前时间的时间戳(同上面的时间戳) |
自定义函数
定义函数
必须使用function关键字
function name([variables]) { statements }
可以使用return语句返回值
使用自定义函数
定义函数时,必须在所有代码块之前,包括BEGIN
$ gawk ' > function test(v1){ > print v1 > } > BEGIN{ > test("abc") > } > ' abc
使用函数库
1.首先需要创建一个存储gawk函数的文件:
$ cat gawk_lib function test(v1){ print v1 } function add(){ print $1+$2+$3 }
2.然后通过使用-f选项来指定函数库即可:
$ cat gawk_lib_test BEGIN{ FS=" " } { add() } $ gawk -f gawk_lib -f gawk_lib_test numbers 6 1368 10363
转贴请保留以下链接
本人blog地址
相关推荐
linux命令行与shell脚本编程.pdf
Linux命令行与shell脚本编程大全_learn-linuxshell
Linux 命令行和shell脚本编程宝典(清晰绝对完整版).pdf,绝对完整的版本,清晰度比160多M的还要好一些,有完整书签,在CSDN上花8分下载了4个part,结果解压不了,超级郁闷。辛苦找到的这个真正完整的可以分享给大家...
《Linux命令行与Shell脚本编程大全》是一本专为Linux初学者编写的经典教材,旨在帮助读者深入理解和掌握Linux操作系统中的基本命令行操作以及Shell脚本编程技术。这本书全面覆盖了从基础到进阶的各种主题,对于想要...
linux脚本+命令总结
一本关于Linux命令行与shell脚本编程的全方位教程,主要包括四大部分:Linux命令行,shell脚本编程基础,高级shell脚本编程,如何创建实用的shell脚本。(编写shell实用查询宝典)
最实用的Linux 命令行和shell脚本编程宝典,是最常用的参考手册。
Linux命令行与shell脚本编程、Linux C库函数及系统调用编程、Linux内核分析即应用、Debian(Ubuntu、Deepin)操作系统爬坑.zip Linux命令行与shell脚本编程、Linux C库函数及系统调用编程、Linux内核分析即应用、...
读书笔记:Linux命令行与shell脚本编程大全 第三版 学习笔记
Linux命令行与shell脚本编程、Linux C库函数及系统调用编程、Linux内核分析即应用、Debian(Ubuntu、Deepin)操作系统爬坑.zip Linux命令行与shell脚本编程、Linux C库函数及系统调用编程、Linux内核分析即应用、...
Linux命令行与shell脚本编程大全_第三版_学习笔记_learn_linux_shell
《Linux命令行与Shell脚本编程大全》是一本深度探讨Linux操作系统中命令行操作和Shell脚本编程的经典著作。本书旨在帮助读者掌握在Linux环境中高效工作所需的技能,无论是日常使用还是进行系统管理、自动化任务,都...
读书笔记:Linux命令行与Shell脚本编程大全
《Linux命令行与shell脚本编程大全》书的笔记_LinuxCommandLineAndShellScriptingBible
读书笔记:Linux命令行与shell脚本编程大全案例
读书笔记:Linux 命令行与 shell 脚本编程大全——学习仓库
读书笔记:《Linux命令行与shell脚本编程大全》书的笔记
Linux命令行与Shell脚本编程大全_shell-code
Linux命令行与shell脚本编程大全案例
读书笔记:Linux命令行与shell脚本编程大全.第3版