⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 awk最新教程.txt

📁 linux下的命令
💻 TXT
📖 第 1 页 / 共 4 页
字号:
内部函数是 awk 提供的函数,可在 awk 程序的任何地方调用。5.1 	数值方面的内部函数int(x)	求出 x 的整数部份,朝向 0 的方向做舍去。例如:int(3.9) 是 3,int(-3.9) 是 -3。sqrt(x)	求出 x 正的平方根值。例 sqrt(4)=2exp(x) 	求出 x 的次方。例 exp(2) 即是求 e*e 。log(x) 	求出 x 的自然对数。sin(x) 	求出 x 的 sin 值。cos(x) 	求出 x 的 cos 值。 atan2(y,x) 	求 y/x 的 arctangent 值,所求出的值其单位是弧度量。rand() 	得出一个随机数值。此随机数值平均分布在 0 和 1 之间。这个值不会是 0,也不会是 1。每次执行awk,rand 产生的数字都相同。 如:awk '{ for (i=1;i<10;i++) { x=rand() print x } }' 执行后,每打一次回车便产生10个0-1之间的随机数。但第一次执行产生 的若干数字如100个和第二次执行产生的100个数字相同。srand(x) 设定产生随机数的开始点为 x。如果在第二次你设定相同的 seed 值,你将再度得到相同序列的随机数值。如果省略引数 x,例如 srand(),则现在的日期、时间会被当成初始值。这个方法可使得随机数值是真正不可预测的。5. 2	字符串方面的内部函数index(in, find)它会在字符串 in 里面,寻找字符串 find第一次出现的地方,返回值是字符串 find出现在字符串 in里面的位置。如果在字符串 in里面找不到字符串find,则返回值为 0。例如:print index("peanut","an")会输出 3。 length(string)求出 string字符串的长度。例如: length("abcde") 的返回值是 5。 match(string,regexp)match函数会在字符串 string 里面,寻找符合 regexp 的最长、最靠左边的子字符串。返回值是 regexp 在 string 的开始位置,即 index值。 match 函数会设定内在变量 RSTART 等于 index,它也会设定内在变量 RLENGTH等于符合的字符个数。如果不符合,则会设定 RSTART 为0、RLENGTH 为 -1。如:awk '{ match("sfsdfgertertrtra","tert") print RSTART,RLENGTH }' 执行后,每次回车都会显示9 4,意为第9位,长度为4 split(string,array,field_seperator)使用split返回字符串数组元素个数。工作方式如下:如果有一字符串,包含一指定分隔符 - ,例如AD2-KP9-JU2-LP-1,将之划分成一个数组。使用 split,指定分隔符及数组名。此例中,命令格式为 split("AD2-KP9-JU2-LP-1",parts_array,"-"),split然后返回数组下标数,这里结果为4。sprintf(format,expression1,...) 与 printf 类似,但是 sprintf 并不输出,而是返回字符串。例如: pi=sprintf(“%.2f (approx.)”,22/7) print pi 将会显示 3.14 (approx.)sub(regexp,replacement,target)在字符串 target里面,寻找符合regexp的最长、最靠左边的地方,以字符串 replacement代替最左边的 regexp。例如: awk '{ str ="water, water, everywhere" sub(/at/, "ith",str) print str }' 结果字符串str会变成 "wither, water, everywhere"gsub(regexp,replacement,target)gsub与前面的 sub类似。在字符串 target 里面,寻找符合 regexp 的所有地方,以字符串 replacement 代替所有的 regexp。例如: str="water, water, everywhere" gsub(/at/, "ith",str) 结果字符串str会变成 wither, wither, everywhere substr(string, start, length)返回字符串 string 的子字符串,这个子字符串的长度为 length个字符,从第start个位置开始。例如:str=substr("washington",5,3) 返回值为"ing" 如果 length没有出现,则返回的子字符串是从第 start个位置开始至结束。例如: awk 'BEGIN { oldstr="washington" } { newstr=substr(oldstr,5) print newstr }’执行后将显示"ington" tolower(string) 将字符串string的大写字母改为小写字母。例如: awk 'BEGIN { oldstr="WASHINGTON" } { newstr= tolower(oldstr) print newstr }’ 执行后显示: washingtontoupper(string) 将字符串string的小写字母改为大写字母。例如: toupper("MiXeD cAsE 123") 返回值为"MIXED CASE 123" 5.3	输入输出的内部函数close(filename)将输入或输出的文件filename关闭。例如:awk '{ print "new line">"new" }'前面的语句的作用是将”new line”这个字符串放入文件new中,注意语句中使用的是”>”符号,其作用将显示内容转向,在转向的同时将文件中原有的内容清除掉,所以不论print语句执行几遍,文件new中的内容都应该只有一行:”new line” 。但执行上例awk语句,敲5次回车后发现文件new中有5行new line,而不是一行。其原因是因为文件new被打开后,没有被关闭,导致再次操作时发生错误。如果需要完成上例所设想的功能,应该使用下面的语句: awk '{ print "new line">"new" close(new) }' 另外,在一个awk中如使用追加符号“>>”可以不使用close语句,但为了避免多个awk语句可能存在对同一个文件的操作,在对文件操作完成后,最好都使用close关闭文件。system(command)此函数允许在awk中使用系统提供的Shell命令,命令执行完毕后将回到 awk程序。例如: awk '{ str=sprintf("head -%d filename",$1 ) system(str)}' 该语句将按输入数字的值取出文件filename的前若干行。注意,在使用格式化语句的时候,首先要将格式化的字符串赋予某个变量,如例子中的str,然后再在system中使用。如果希望将命令执行的结果截获下来,供awk中的语句使用,可以使用管道。如: awk ' { "cat filename|wc -l" | getline var #将文件filename的长度赋予变量var print var }' 管道线前面的语句可以不包括在system中。 getline函数的在这里的作用是将通过管道获得的值存储于var变量。 getline awk提供将输入数据分解为记录的功能,但对于某些任务来说,仍不能满足数据处理的要求。比比如,在下列数据文件当中数据是以若干行为单位存放的: more data: begin zhangqiang 24 nan 96 wanggang 23 nan 97 zhaoyu 22 nu 98 end …… 如上所示,begin和end之间的数据是一个整体,在文件中的数据全部是以这种方式存放,当然在处理时也需要读入一个单位后统一进行,在这种情况下,就可以用到getline函数。 getline函数用以读取下一行的数据并进行字段分解操作,设置NF,NR和FNR。如果有一个记录,getline返回1,如果遇到文件结束,返回 0,如果出现错误,返回-1。举例: awk '/^begin/ { N=0 #在找到开始标志begin时,将变量N置0 while (getline && $0 !~ /^end/) #取下一行,并且下一行不是end时 { f[++N]=$0 } #将读入的数据存入数组f中 for (i=1;i<=N;i++) #对begin与end之间的数据进行处理(已 { printf("%s " , f[i]) } #存入到数组f中。 print "" #换行 }' data getline函数还有其它用法: getline x #将下一个记录读入变量x中,不作分解,不设置NF getline < “filename” #从指定文件filename中读取一行(存入$0中),而不是从当前文件中,对NR或FNR没有影响,但对字段进行分解并且设置NF。再或者,如上页例题中所示,通过管道截取命令执行后的结果。第六章 自定义函数(User-defined Functions) 复杂的 awk 程序常常要通过自定义函数来简化。自定义的函数的使用与内部函数的使用方法一样。 1) 函数定义的格式函数的定义可以放在 awk程序的任何地方。 一个自定义的函数其格式如下: function name (parameter-list) { body-of-function } name 是所定义的函数的名称。一个正确的函数名称可包括一序列的字母、数字、下标线 (underscores),但是不能用数字做开头。 parameter-list是函数的参数列表(argument),各个参数之间以逗点隔开。 body-of-function包含 awk 的描述 (statement)。它是函数定义里最重要的部份,它决定函数实际要做何种事。 2)函数定义的例子下面这个例子,会将每个记录的第一个字段值的平方与第二个字段之值的平方加起来。 awk ‘{ print $1,$2,"sum =",SquareSum($1,$2) } function SquareSum(x,y) { sum=x*x+y*y return sum }’ filename 在定义了函数SquareSum之后,对每一行数据的处理只需经过一次调用就可以。但定义自定义函数最大的好处还是可以在不同的地方调用,而不必每次都写上一堆,此外还使程序结构清楚,易读,易维护。第七章 示例 awk '{ if (NF > max) max = NF } END { print max }' filename 此程序会输出所有输入行中,包含字段最多的行的字段数。 awk 'length($0) > 80' filename 此程序会输出一行超过 80 个字符的每一行。此处只有 pattern 被列出,action 是采用缺省的 print。 awk 'NF > 0' filename 对于拥有至少一个字段的所有行,此程序皆会输出。这是一个简单的方法,将一个文件里的所有空白行删除。 awk '{if (NF > 0) print}' filename 对于拥有至少一个字段的所有行,此程序皆会输出。这是一个简单的方法,将一个文件里的所有空白行删除。 awk 'BEGIN { for (i = 1; i <= 7; i++) print int(101 * rand()) }' filename 此程序会输出 0 到 100 之间的 7 个乱数值。 ls -l files| awk 'BEGIN { x=0 } { x += $4 } END { print "total bytes: " x }' filename 此程序会输出所有指定的文件之bytes数目的总和。 expand file | awk '{if (x < length()) x = length()} END {print "maximum line length is " x}' filename 此程序会将指定文件里最长一行的长度输出。expand 会将 tab 改成 space,所以是用实际的右边界来做长度的比较。 awk 'BEGIN {FS = ":"} {print $1 | "sort"}' /etc/passwd 此程序会将所有用户的login名称,依照字母的顺序输出。 awk '{nlines++} END {print nlines}' filename 此程序会将一个文件的总行数输出。 awk 'END {print NR}' filename 此程序也会将一个文件的总行数输出,但是计算行数的工作由awk来做。 awk '{print NR,$0}' filename 在输出文件的内容时,会在每行的最前面输出行号,它的功能与 'cat -n' 类似。 □ 附录 例程分析 1. 关机帐号大家都知道在UNIX系统中,关机命令都必须在超级用户执行(其它用户没有关机权限),而在有些情况,我们并不希望直接使用UNIX系统的人知道根用户的口令(如网点端的操作员),而又想让他可以直接正常关闭机器, 并且在关机时,系统中的其它注册用户最好都退到login:状态. 下面是一个运行在UNIX系统上的关机程序,主要是针对操作员设计的,使用它可以在不知道超级用户口令的情况下,通过系统提供的关机命令正常关闭计算机, 并且它在关机之前检测其它用户是否都已退出,避免系统数据不必要的损失。 一般情况下,在UNIX系统中建立一个关机帐号有以下两个步骤: 1. 在系统中建立一个普通用户,如halts,其用户主为halts,用户组为group.将关机权限赋予该用户. 2. 在该用户目录下编辑一个关机程序,即下例所示(程序名为halts),赋予其可执行权限.在该用户的.profile文件的第一行增加trap 'clear;exit' 0 1 2 3 5 15,在最后一行增加一行exec halts #halts: 关机帐号程序,用以关闭计算机 1999/3/21 trap 'clear;exit' 0 1 2 3 5 15 #截获中断信号,当后面所列信号出现时执行单 #引号中的命令,即先清屏然后退出 #===============================================================================# testscreen() #函数,用于测试哪些屏幕还没有退出 { #函数体开始符号 she=`tty` #变量she被赋予当前所在屏幕的设备名 if [ "$she" != "/dev/tty01" ] #如果变量she的值不等于第一个屏幕的设备名 then #则 echo "\n\t\t请在第一屏关机 !\c" #显示“请在第一屏关机 !”字样 sleep 2 #等待2秒钟后 exit 0 #退出程序 fi #if语句结束 } #函数体结束符号 #===============================================================================# yesyn() #函数,用于测试用户的输入是‘y’还是‘n’ { #函数体开始符号 while echo "\n$* (y/n) \c">&2 #当正常显示提示信息($*)后进入循环 do #作以下操作 read yn rest #读用户输入并将输入放入yn变量中 case $yn in #当变量yn的值为 [Yy]) echo ; return 0 ;; #大写字母Y或小写字母y时,函数返回0 [Nn]) echo ; return 1 ;; #大写字母N或小写字母n时,函数返回1 *) echo "\n\t\t稍后请回答 y 或 n !\c">&2 #其它输入时,显示“稍后请回答 y 或 n !” sleep 1 #等待1秒钟 clear ;; #清屏 esac #case语句结束 done #while语句结束 } #函数体结束符号 #===============================================================================# menu() #函数,用于显示如下菜单 { #函数体开始符号 echo #换行 echo "\t\t ┏━━━━━━━━━━━━┓" #显示菜单框 echo "\t\t ┃ 1) 强行 关 机 ┃" #显示选项 echo "\t\t ┃ 2) 重 新 测 试 ┃" #显示选项 echo "\t\t ┃ 3) 退 出 ┃" #显示选项 echo "\t\t ┗━━━━━━━━━━━━┛" #显示菜单框 echo "\n\t\t 请输入选择: \c" #显示“请输入选择” } #函数体结束符号 #===============================================================================# exam() #函数,用于检测有哪些屏幕还没有退出 { #函数体开始符号 clear #清屏 status=0 #状态变量stutes被赋初值0(表示全部退出) sum=`who|wc -l` #变量sum被赋于尚未退出的用户数 if [ $sum -ne 1 ] #如果该数目不等于1 then #那么 status=1 #状态变量stutes被赋初值1(表示有用户尚未退出) echo "^G^G" #响铃,注意^G是一个组合键Ctrl-g echo "\n\n" #换行 for i in `who|awk ' $2!="tty01" { which=substr($2,4,2) print which }'` #该语句首先将who命令的输出传递给awk语句,awk语句检测输入的 #每一行的第二个字段,当这个字段的值不是"tty01"时,取出该字段 #的第三四位,并将其依此赋予变量which,然后将变量which的值输出 #当以上语句有输出时,将输出依次赋于变量i,进入for循环语句 do echo "\t\t\t第 $i 屏尚未退出 !" #显示“第 n 屏尚未退出 !”,n的值取自变量i done echo "\n\t\t\t请退出上述屏幕后再进行关机 !" #显示字符串 echo "\n\t\t\t按回车键继续 \c" #显示字符串 read key #读用户输入,并将其放入变量key中。其作用是 #等回车键被按下后,和序继续执行。 fi return $status #将变量status的值作为函数的返回值 } #===============================================================================# downs() #函数,用于关闭计算机 { echo "请等待......" #显示"请等待......" 字样 /tcb/bin/asroot shutdown -g0 -y #执行关机命令 exit 0 #退出程序 (此句亦可省略) } #===============================================================================# main() #主函数,控制整个程序的流程 { clear #清屏 testscreen #检测是否在第一屏 echo "^G\c" #响铃 yesyn "\n\n\t\t本程序用于关闭计算机 是否要关闭(Y/N): \c" #显示"是否关机(Y/N)"的提示,接收用户输入 if [ $? -eq 1 ] #当函数yesyn的返回值为1时 then #就 clear #先清屏 exit 0 #然后退出程序 fi while true #无条件进入while循环语句 do exam #检测是否还有用户没有退出 if [ $? -eq 0 ] #当函数exam的返回值为0时 then #那么 downs #执行关机函数 else #否则 menu #执行菜单显示函数 read key #读用户输入,并将其放入变量key中 case $key in #当变量key的值为 1) downs ;; #1时,执行关机函数downs 3) exit 0 ;; #3时,退出程序 *) echo "请回答y或n">&2;; #其它输入时, 先显示"请回答y或n"后无条件进入下次循环 esac #case语句结束 fi #if语句结束 done #while语句结束 } #===============================================================================# main #执行主函数 2. 临测程序 下面是一个网络连通检测程序,它可以在屏幕上直观地反映出网络中各目标网点的连通状况。程序循环检测,直到被中断为止。从简单易读的角度出发,该段程序对屏幕显示的格式只作了简单处理,在网点数较多的情况下,需要稍作修改。 #本程序用以检测客户端连通情况 1999/3/21 #============================================================================# tests() #函数,用以检测一个网点端的连通状况,连通返回0,否则返回1。 #网点名由位置参数确定 { num=`ping -c 1 $1|awk '$2=="packets" { data=substr($7,1,1) print data }'` #上面一句是将“ping -c 1 $1”命令的输出转向给awk语句,awk将第二个 #字段为“packets”的那一行的第七个字段的第一个字符赋予变量num。此数 #是“ping -c 1 $1”命令返回的丢包率,0为通,非0为不通 if [ $num -eq 0 ] #如果变量num的值为何0 then #则 return 0 #返回0值 else #否则 return 1 #返回1 fi #if语句结束 } #============================================================================# all() #函数,用以检测所有网点端的网络连通性 { hang=3 #设置行变量的初始值为3 lie=10 #设置列变量的初始值为10 for i in lan0 serial0 zongying yiying erying sanying siying wuying liuying #当i变量为“lan0 serial0 ......wuying liuying”等网点端机器名时 do #作如下工作 tput cup $hang $lie #将光标定位在初始位置 echo "\t\t^[[36m →^[[37m${i}: \c" #显示当前网点机器名 tests $i #用tests函数测试该网点是否为通 tput cup $hang $lie #光标定位于$hang $lie if [ $? -eq 0 ] #如果tests函数的返回值等于0 then #则 echo "\t\t ^[[33m→^[[37m ${i}\t ^[[32m ● ^[[37m\c" #显示绿色● sleep 1 #等待1秒钟 else #否则 echo "\t\t ^[[33m→^[[37m ${i}\t ^[[31m ● ^[[37m\c" #显示红色● fi hang=`expr $hang + 2` #行变量加二 sleep 1 done tput cup 22 10 #光标定位于 22 10 echo " 呼市育财信用社线路连通状况表 ^[[32m●^[[37m: 通 ^[[31m●^[[37m: 不通" #显示 ” 呼市育财信用社线路连通状况表 ●(绿色): 通 ●(红色): 不通” } #============================================================================# main() #主函数 { clear #清屏 tput cup 22 10 #光标定位于 22 10 echo " 呼市育财信用社线路连通状况表 ^[[32m●^[[37m: 通 ^[[31m●^[[37m: 不通" while true #无条件进入while循环 do all #调用all函数 done } #============================================================================# TERM=ansi #给终端类型变量赋值ansi export TERM #声明TERM变量 main #执行主函数 3. 数据查询程序相信大家都有同感,在需要查寻所有储种户数和金额的时候,在菜单中或数据库中一项一项地查找是一件很繁琐的事情,特别是在初始建帐,需要核对录入数据正确性的时候。下面一段程序就是为自动查询数据设计的。当然它十分简单,比如它没有检测输入所号的否合法性等,但比较易读和实用。 #本程序用于查询Informix数据库中某个储蓄所活期、定期、零整储种的记录数 #及总金额,查询结果显示在屏幕上 #==========================================================================# zzbsum() #过程,用于获得某所定期储种的记录数及总金额 { echo "\c" #换行 dbaccess bankstar</dev/null 2>/tmp/error unload to /tmp/jieguo0 select sum(jce) from zzb where zh[1,7]="$1"; unload to /tmp/jieguo1 select count(*) from zzb where zh[1,7]="$1"; END #以上语句以Here文本的方式,调用dbaccess工具中的SQL语句将某所 #定期储种的总金额及记录数分别下载到/tmp/jieguo0,/tmp/jieguo1文件中 #其中,储蓄所号是由该过程的位置参数(即$1)确定的 sum0=`awk -F '|' '{ print $1 }' /tmp/jieguo0` sum1=`awk -F '|' '{ print $1 }' /tmp/jieguo1` #以上两句分别取出/tmp/jieguo0,/tmp/jieguo1文件中的第一个字段,并 #将其分别赋予变量sum0及sum1 echo "\t整整簿总结存额: $sum0 \c" echo "\t整整簿总户数: $sum1" #以上两句将字符串及变量的值分别显示到屏幕上 } #==========================================================================# zzb() #过程,用于获得某所定期储种某一档次(存期)的记录数及总金额 { #过程中的语句用法同hzbsum(),存期由该过程的位置参数(即$2)确定 echo "\c" dbaccess bankstar</dev/null 2>/tmp/error unload to /tmp/jieguo0 select sum(jce) from zzb where zh[1,7]="$1" and qx="$2"; unload to /tmp/jieguo1 select count(*) from zzb where zh[1,7]="$1" and qx="$2"; END sum0=`awk -F '|' '{ print $1 }' /tmp/jieguo0` sum1=`awk -F '|' '{ print $1 }' /tmp/jieguo1` echo "\t整整簿${2}总结存: $sum0 \c" echo "\t整整簿${2}总户数: $sum1" } #==========================================================================# #依照上面的形式很容易写出活期、零整的过程:hzbsum()、lzbsum()、lzb() main() #主过程,询问储蓄所号及调用子过程 { clear #清屏 echo "\n\n\t\t请输入储蓄所号 : \c" #显示提示字符串 read cxsh #读取输入 echo #换行 hzbsum $cxsh #调用过程hzbsum,变量cxsh的值为位置参数 echo #换行 zzbsum $cxsh #调用过程zzbsum,变量cxsh的值为位置参数 for i in 03 12 24 36 60 96 do zzb $cxsh $I done #以for语句循环调用过程zzb,第二个位置参数 #分别为 03 12 24 36 60 96 echo #换行 lzbsum $cxsh #调用过程lzbsum,变量cxsh的值为位置参数 lzb $cxsh 12 #调用过程lzb,“03”作为第二个位置参数,以下用法相同 lzb $cxsh 36 lzb $cxsh 60 rm /tmp/jieguo0 /tmp/jieguo1>/dev/null 2>/dev/null #删除临时文件 } #===========================================================================# main #调用main主过程

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -