您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > shell----编程实例
1.判断一个文件是否是可执行文件,且判断能否在PATH中找到,有三种结果(一)找到且可执行0(二)非情况一(2)没找到或者是不可执行1(3)没找到2函数in_path:判断传入文件是否可执行,若可执行(且存在)返回0,否则返回1;分析:为测试传入文件是否在PATH所有的目录中,需取得PATH中的每个路径,可用循环,但需要设定环境中的分隔符(借助环境变量IFS)为PATH中的分隔符冒号”:”注:$IFS输入分隔符.当shell读取输入数据的时候,会把一组字符看做是单词之间的分隔字符,它们通常是空格,制表符,和换行符.函数调用方式为:in_pathfilenamein_path(){cmd=$1#$1为函数的参数1,以此类推retval=1#定义返回值变量oldIFS=$IFSIFS=:#设置新的IFS,并保存原来的以恢复使用fordirectoryin$PATH#for循环结构二:for–indoif[-xdirectory/$cmd];then#if条件语句之同行表示以分号隔开retval=0#-x判断文件有是否有可执行权限donedoneIFS=$oldIFS#恢复原来IFS,returnretval}注:1.函数的结构,没有形参2.变量的引用需要符号$,而变量的定义或赋值则不需要。3.赋值要无间隙,条件要间隙改进:1.将路径、分隔符均作为函数的参数传入,应用得到扩展。补充,in_path函数不能对绝对路径的文件处理,需写个函数对这一情况单独处理checkForCmdInPath(){var=$1#首先判断传入的非空串是否为绝对路径,即检测第一个字符是不是”/”,如果是,直接测–xif[$var!=“”];then#条件等价于-n$varif[“${var%${var#?}}”=‘/’];then#等价于$(echo$var|cut-c1)if[!-x$var];thenreturn1#notfoundornotexecutablefielif!inpath$var;thenreturn2#notfoundinPATHfifi}注:此函数让人一头雾水,详解如下:1)表达式${var%${var#?}}作匹配用,分解为${var%expr}${var#expr},expr为正则表达式(?匹配单一字符)后者(带#的)返回expr与var匹配成功位置之后的所有内容,此处为var中第一字符之后的所有。前者(带%的)返回expr与var匹配成功位置之前的所有内容,此处应为var的第一个字符。等价于$(echo$var|cutc1)即取第一字符。等价于${var:beginpos:size}中beginpos=0,size=1时的结果。var的符号放在外面了,假设$var为$1,则表达式表示为${1%${1#?}}2)关于if的条件判断与C语言中的理解不一致,反映在上述的elif语句中的条件。理解如下:shell中的if条件可以是表达式(需加方括号[]),另外还可以是命令或函数(不需方括号),当命令执行成功时会后继执行具体操作,经测试,C语言中所说的true在shell中用0表示,即if0,才执行then,因为linux下的程序实现都是当返回0时表执行成功。3)若函数中没有返回值,则它默认返回0,表执行成功。函数的编写若遵从以上的原则,则对条件的理解依旧像C语言中的TRUE,FALSE一样理解==============完善程序代码=====================================#!/bin/bashin_path()...#函数实现区域处理不路径返回0表找到、可执行,否则返回1###############################checkForCmdInPath()...#函数实现区域处理带路径和不带路径的返回1表没找到或不可执行,返回2表没找到。默认0表找到#####################################代码执行起始位置##############if[$#-nq1];thenecho“Usage:$0command”#$0表此执行文件(具体内容以执行此文件时的输入串为准)exit0fi#调用函数,并经第一个参数传给函数checkForCmdInpath$1#对函数返回的结果进行判断$?为函数的返回值,case$?in#case控制结构的格式,注意红色部分。0)echo“foundinPATH”;;1)echo“notfoundornotexecutable”;;2)echo“notfound”;;#*);;类似于C语言中的default========================================================================2.写一个脚本,检测用户输入串的合法性,要求串由大小写字母、数字组成,无标点、特殊符号、空格。思路:将输入的串中非字母数字的内容删除或替换为空后若和原来输入的相同则合法,否则不合法。isvalidAlphaNum(){compressed=”$(echo$1|sed's/[^[:alnum:]]//g')”#替换不合要求字符为空if[“$compressed”!=“$1”];thenreturn1#notvalideelsereturn0#validefi}注:1.关于引用变量时是否需要双引号的说明如果只是输出,可以不用双引号如果变量值代的内容中无空格,表达,特殊符号,在引用时可以不需要双引号,反之,最好带双引号,否则在变量处理时很有可能会出现“参数过多”等莫名其妙的错误信息。2.关于匹配处理,sed是单行编辑程序。sed‘s/str1/str2/g’file将文件file中每行内str1替换为str2[[:alnum:]]表示所有字母和数字中的任一个字符。若只是[:alnum:]则表示方括号中的任一个字符。[^[:alnum:]]表除了所有字母数字外的任一字符。如果是直接向脚本传字符串,则带空格的字串会被脚本自行分解为多个参数,所以可采用从标准输入读取的方式获得字串。==============完善程序代码=====================================#!/bin/bashisvalidAlphaNum()...#函数体,判断字串的合法性echo-n“Enterinput:”#-n强制不换行readinput#读取内容存到input中,无$符号if!isvalidAlphaNum“&input”;then#加引号,否则可能会出错。echo“invalide”exit1elseecho“valide”fiexit0===============================================================3.输入一个“monthdayyear”格式的日期串,程序将处理”month”为其英文单词的前三个字母,第一个字母大写,其余的小写。思路:首先判断month是数字、还是单词,若是数字,则可查“数字—month”映射表(自定义case结构);若是单词,则取前三个字母,并格式化。函数monthnoToName()将month数字转换为month名monthnoToName(){case$1in1)month=Jan;;2)month=Feb;;3)month=Mar;;4)month=Apr;;5)month=May;;6)month=Jun;;7)month=Jul;;8)month=Aug;;9)month=Sep;;10)month=Oct;;11)month=Nov;;12)month=Dec;;*)echo$0:Unknownnumericmonthvalue$1&2;exit1#default,esac#return0}假设通过传三个参数到脚本——monthdayyear----------实现代码------------------------------#!/bin/bashif[$#-ne3];then#若参数个数不为3,则有误echo“Usage:$0monthdayyear”exit1fi#判断参数1是数字还是单词,方法替换串中所有数字,若结果为空,则为数字,否则为单词。if[-n$(echo$1|sed‘s/[[:digit:]]//g’)]#-n检测串是为空thenmonthnoToName$1#数字else#取第一个字母并将其变为大写,再将结果与取出的第二三字母组合month=”$(echo$1|cut–c1|tr'[:lower:]''[:upper:]')“month=”$month$(echo$1|cut-c2-3|tr'[:upper:]''[:lower:]')”fiecho$month$2$3#输出结果exit0-------------------------------------------------注:1.外围可以使用函数中定义的变量,如函数monthnoToName中定义的month变量,最后echo会用到它。2.多管道(|)的使用3.month变量的合并,$var$var4.trSET1SET2转换/删除/替换命令,将默认将SET1替换为SET2tr默认从标准输入读取,处理后写入标准输出。5.cut–c2-3file取文件每行第2,3字母。扩展:处理MM/DD/YYYYorMM-DD-YYYY的形式。在判断三个参数前执行命令set--$(echo$1|sed's/[\/\-]//g')。set的–-命令可以将其后的参数赋予位置参数($1,$2,...)。链接set指令用法4.格式化输出大数字,使输出结果更容易让人知道该输出数字的数量级。默认用逗号分隔整数部分,用点号分隔整数与小数部分,当然用户也可以使用–d指定整数的分隔符,用-t指定整数与小数部分的分隔符。算法:1232342142.423023==默认:1,232,342,142.423023(1)首先分开整数部分integer和小数部分decimal,sed–d.-f1和sed–d.-f2分别取两部分。(2)整数部分的处理:当作数字来处理%运算/运算1)每次取整数低三位,长度小于3就补前缀0(避免出现漏0情况,例如低三位为003时,取后便为值3)2)将此次得到的三位与上一次得到的三位用分隔符(如果没有指定就默认)组合起来。3)整数去掉低三位,继续操作1)。当此整数小于等于999就不再继续。当字串来处理:1)每次取低三位,cut–c$((${#str}-2))-${#str}${#str}为str的长度,必须为大括号。$(())的内部为str长度-2,代表倒数低三个字符。因为内部是减法,所有此为双小括号。2)原串每次都要裁掉尾部三个字符,每次取到的字串的长度为循环判断条件。函数nicenumber()作如上处理nicenumber()#传入integer.decimal如2000023.2,32232332等{#分别取整数部分和小数部分integer=$(echo$1|cut–d.–f1)decimal=$(echo$1!cut–d.–f2)#判断小数部分是否存在,因为这涉及连接整数和小数的连接符问题#设DD为整数和小数之间分隔符,默认为.if[–n$decimal];then#若非空,即有小数部分。#以下四句可用一句表示:result=”${DD:=”.”}$remainder$result”if[-z$DD];then#判断用户是否自定义整数与分隔符,若空DD=.firesult=$DD$decimal#在小数部分前加分隔符。fithousand=$integerwhile[thousand–gt999]doremainder=$((thousand%1000))while[${#remainder}–lt3];do#${#remainder}为remainder串的长度remainder=0$remaind
本文标题:shell----编程实例
链接地址:https://www.777doc.com/doc-4844651 .html