目录
自定义函数
递归-自己调用自己
上机练习 12
Shell 工具
sort
sed
awk
上机练习 13
自定义函数
 name(){  
 
 action;  
 
 }  
 
 function name  
 
 {  
 
 Action;  
 
 }  
 
 name  
 
 因为 shell 脚本是从上到下逐行运行,不会像其它语言一样先编译,所以函数必  
 
 须在调用  
 
 之前,先声明。  
 
 函数返回值,return 后只能跟数值 n(0-255)  
 
 接收返回值方法:在函数内部使用 echo 命令将结果输出,在函数外部使用$()  
 
 或者``捕获  
 
 结果。  
 
 #  无输入无返回  
 
 hello (){  
 
 echo  "test"  
 
 }  
 
 hello  
 
 # 写一个自定义函数,计算两个输入参数的和  
 
 he (){  
 
 s=0  
 
 s=$(( $1  +  $2 ))  
 
 echo  " $s "  
 
 }  
 
 he 3 65  
 
 jieguo=`he 3 65`  
 
 echo  " 和是: $jieguo "  
 
 可以输入参数  
 
 read -p " 请输入第一个数: " n1  
 
 read -p " 请输入第二个数: " n2  
 
 jieguo=`he $n1 $n2`  
 
 echo " 和是: $jieguo"  
 
 # 也可以使用  shell  位置参数传递到函数 可以互相调用  
 
 he(){  
 
 date  
 
 hello  
 
 s=0  
 
 s=$(($1 + $2))  
 
 echo "$s"  
 
 }  
 
递归-自己调用自己
 #  输入一个目录显示里面的所有目录  
 
 fun(){  
 
 for i in `ls $1`  
 
 do  
 
 if [ -d $1/$i ]  
 
 then  
 
 echo $i  
 
 fi  
 
 done  
 
 }  
 
 fun /root  
 
 #  输入一个目录显示里面的所有目录及其子目录  
 
 echo $i  
 
 fun $1/$i  
 
上机练习 12
 # 1. 编写函数 ,  函数传入三个参数 , 输出积  
 
 # product()  
 
 # {  
 
 #  
 
 p=$(($1*$2*$3))  
 
 #  
 
 echo $p  
 
 # }  
 
 # product 2 4 5  
 
 # 2. 编写函数,传递一个数字参数  5 ,实现  1  到  5  的累加,返回和,输出 " 和是:  
 
 15"  
 
 # sum()  
 
 # {  
 
 #  
 
 sum=0  
 
 #  
 
 for i in `seq 1 $1`  
 
 #  
 
 do  
 
 #  
 
 sum=$(($sum+$i))  
 
 #  
 
 done  
 
 #  
 
 echo " 和是 $sum" # }  
 
 # sum 5  
 
 # sum 6  
 
 # sum 10  
 
 # 3. 编写函数 , 当该函数没有参数或参数多于  2  个 ,  输出 -1, 只有一个参数时 ,  输出  
 
 1, 有两个参数  
 
 #  时 ,  输出  2  
 
 #  提示:使用 $# 判断参数的个数  
 
 # nnumber()  
 
 # {  
 
 #  
 
 if [ $# -gt 2 -o $# -eq 0 ]  
 
 #  
 
 then  
 
 #  
 
 echo -1  
 
 #  
 
 else  
 
 #  
 
 echo $#  
 
 #  
 
 fi  
 
 # }  
 
 # nnumber  
 
 # nnumber 1  
 
 # nnumber 1 2  
 
 # nnumber 1 2 3  
 
 # 4. 编写函数,实现传入一个目录参数,将该目录下(递归)所有的文件都打印  
 
 出来(遇  
 
 #  到文件则打印,遇到目录则继续调函数递归)  
 
 # PrintFile()  
 
 # {  
 
 #  
 
 if [ -d $1 ]  
 
 #  
 
 then  
 
 #  
 
 for i in `ls $1`  
 
 #  
 
 do  
 
 #  
 
 if [ -f $i ]  
 
 #  
 
 then  
 
 #  
 
 echo "$1/$i"  
 
 #  
 
 else  
 
 #  
 
 PrintFile $i  
 
 #  
 
 fi  
 
 #  
 
 done  
 
 #  
 
 else  
 
 #  
 
 echo $1  
 
 #  
 
 fi  
 
 # }  
 
 # PrintFile /root  
 
 # PrintFile age.txt  
 
 # 5. 编写函数,传入一个数字  n ,实现  n  的阶乘 , 效果如下: # factorial()  
 
 # {  
 
 #  
 
 echo " 请输入数字 :$1"  
 
 #  
 
 echo -n " 根据数字 ${1} 得到的阶乘表达式是: $1!="  
 
 #  
 
 f=1  
 
 #  
 
 for i in `seq $1 -1 1`  
 
 #  
 
 do  
 
 #  
 
 echo -n $i  
 
 #  
 
 if [ $i -eq 1 ]  
 
 #  
 
 then  
 
 #  
 
 echo -n "="  
 
 #  
 
 else  
 
 #  
 
 echo -n "*"  
 
 #  
 
 fi  
 
 #  
 
 f=$(($f*$i))  
 
 #  
 
 done  
 
 #  
 
 echo $f  
 
 # }  
 
 # factorial 4  
 
 # factorial 5  
 
 # factorial 6  
 
Shell 工具
sort
 sort  命令是在  Linux  里非常有用,它将文件进行排序,并将排序结果标准输出。  
 
 参数:指定待排序的文件列表  
 
 
 
 shell 下面建立如下文件 sort.txt bb:40:5.4  
 
 bd:20:4.2  
 
 xz:50:2.3  
 
 cls:10:3.5  
 
 ss:30:1.6  
 
 按照“:”分割后的第三列倒序排序。  
 
 sort -t ":" -nrk 3 /root/shell/sort.txt  
 
 bb:40:5.4  
 
 bd:20:4.2  
 
 cls:10:3.5  
 
 xz:50:2.3  
 
 ss:30:1.6  
 
 grep  、 sed 、 awk  被称为  linux  中的 " 三剑客 "  。  
 
 我们总结一下这三个 " 剑客 " 的特长。  
 
 grep  更适合单纯的查找或匹配文本  
 
 sed  更适合编辑匹配到的文本  
 
 awk  更适合格式化文本,对文本进行较复杂格式处理  
 
sed
 sed: stream editor (流编辑器)的简称。  
 
 它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中( “ 模式空  
 
 间 “ ),  
 
 接着用  sed  命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。  
 
 接着处理  
 
 下一行,这样不断重复,直到文件末尾。  
 
 p  打印,亦即将某个选择的数据印出。通常  p  会与参数  sed -n  一起运行~  
 
 i  插入,  i  的后面可以接字串,而这些字串会在新的一行出现 ( 目前的上一行 ) ;  
 
 a  新增,  a  的后面可以接字串,而这些字串会在新的一行出现 ( 目前的下一行 )  
 
 s  取代,可以直接进行取代的工作哩!通常这个  s  的动作可以搭配正规表示法!  
 
 1. 显示文件的第  2  行的内容:  
 
 sed -n '2 p' /root/shell/sort.txt  
 
 2. 显示文件的第  2  行到第  4  行的内容:  
 
 sed -n '2,4 p' /root/shell/sort.txt  
 
 3. 将文件中的  bb  全部替换为  BB  
 
 sed 's/bb/BB/g' /root/shell/sort.txt  
 
 4. 以文件  bb  开头的上一行添加  
 
 sed '/^bb/i hello' /root/shell/sort.txt  
 
 5. 将文件中的  d  全部删除  
 
 sed 's/d//g' /root/shell/sort.txt  
 
 注:可以使用管道符连续处理 , 接着重定向保存,使用 \ 拼接换行 
 
awk
 一个完整的  awk  命令形式如下:  
 
 awk [options] 'BEGIN{ commands } { commands } END{ commands }' file  
 
 -v  指定  FS  和  OFS  字段分隔符和输出字段分隔符  
 
 内置参数:  
 
 NF  分割完字段的数量  
 
 $1  代表文本行中的第  1  个数据字段;  
 
 $2  代表文本行中的第  2  个数据字段;  
 
 输出指定列: {print $1,$2}  
 
 分隔符相同的情况输出一整行: {print}  
 
 1. 以 : 为分隔符,打印第  2  列和第  1  列  
 
 awk -v FS=":" '{print $2,$1}' /root/shell/sort.txt  
 
 2. 以 : 为分隔符,打印第  2  列和第  1  列,列之间用 , 分割  
 
 awk -v FS=":" -v OFS="," '{print $2,$1}' /root/shell/sort.txt  
 
 3. 添加列保存为  csv ,下载,使用  excel  查看  
 
 awk -v FS=":" -v OFS="," 'BEGIN{print "one,two,three"}{print $2,$1,$3}'  
 
 /root/shell/sort.txt > /root/shell/sort.csv  
 
 4. 第二列大于  30  
 
 awk -v FS=":" '{ if($2>30){print $2}}' /root/shell/sort.txt  
 
 5. 行列总数量  
 
 awk -v FS=":" 'BEGIN{n=0}{for(i=1;i<=NF;i++){n++} }END{print n}'  
 
 /root/shell/sort.txt  
 
 注:可以使用管道符连续处理 , 接着重定向保存,使用 \ 拼接换行  
 
上机练习 13
 # 创建 shell 脚本来完成  
 
 # 1.复制网卡文件/etc/sysconfig/network-scripts/ifcfg-ens33 到家目录,  
 
 并且改名为  
 
 # wangka.txt  
 
 # cp /etc/sysconfig/network-scripts/ifcfg-ens33 /home/  
 
 # mv /home/ifcfg-ens33 /home/wangka.txt  
 
 # 2.找到含有 IP 的行输出  
 
 # cat -sb /home/wangka.txt | grep "IP"  
 
 # 3.显示文件的第 3 行到第 5 行的内容  
 
 # sed -n "3,5 p" /home/wangka.txt  
 
 # 4.将文件中的 255 全部替换为 250  
 
 # sed 's/255/250/g' /home/wangka.txt  
 
 # 5.以文件 IPADDR 开头的上一行添加 hello  
 
 # sed '/^IPADDR/i hello' /home/wangka.txt  
 
 # 6.找到所有 DNS,并且删掉  
 
 # sed 's/DNS//g' /home/wangka.txt  
 
 # 7.使用管道符连续处理 4. 5. 6. 题,并且重定向结果保存为 wangka.csv # sed 's/255/250/g' /home/wangka.txt | sed '/^IPADDR/i hello' | sed  
 
 's/DNS//g' > /home/wangka.csv  
 
 # 8. 根据 wangka.csv 文件自己灵活处理重定向为 ip.txt,内容如下:  
 
 # 192.168.145.151  
 
 # 250.250.250.0  
 
 # 192.168.145.2  
 
 # 8.8.8.8  
 
 # 114.114.114.114  
 
 # sed -n '19,23 p' /home/wangka.csv | awk -v FS="\"" '{print $2}' >  
 
 /home/ip.txt  
 
 # 9. ip.txt 中以.分割,按照第一列进行降序排序  
 
 # sort -t "." -nrk 1 /home/ip.txt  
 
 # 10. ip.txt 中以.为分隔符,打印第 1 列和第 2 列  
 
 # awk -v FS="." '{print $1,$2}' /home/ip.txt  
 
 # 11. ip.txt 中以.为分隔符,打印第 3 列和第 4 列,列之间用,分割  
 
 # awk -v FS="." -v OFS="," '{print $3,$4}' /home/ip.txt  
 
 # 12. ip.txt 中以.为分隔符,列之间用,分割,且加一行,保存为 ip.csv,格式  
 
 如下:  
 
 # one,two,three,four  
 
 # 192,168,145,151  
 
 # 250,250,250,0  
 
 # 192,168,145,2  
 
 # 8,8,8,8  
 
 # 114,114,114,114  
 
 # awk -v FS="." -v OFS="," 'BEGIN{print "one,two,three,four"}{print}'  
 
 /home/ip.txt > /home/ip.csv  
 
 # 13. 在家目录下创建一个 names.txt 的文件,写入班级的所有同学的姓名,每  
 
 个一行,每  
 
 # 次随机产生一个姓名  
 
 # 终端执行  
 
 # touch /home/names.txt  
 
 # vim /home/names.txt  
 
 # i 编辑模式  
 
 # 输入  
 
 # ESC  
 
 # :wq!  
 
 # shell 执行  
 
 # sed -n "$(($RANDOM%12+1)) p" /home/names.txt  
 
 # 14. 批量修改家目录下的文件扩展名,使用位置参数传递两种扩展名,例如  
 
 txt 文件为 csv  
 
 # 文件。(注:碰到特殊符号使用\进行转义)  
 
 # UpdateType()  
 
 # {  
 
 # ls /home > /root/updatefile.txt # sed "s/.$1/.$2/g" /root/updatefile.txt > /root/updatefile1.txt  
 
 # count=1  
 
 # for i in `ls /home`  
 
 # do  
 
 #  
 
 f=$(sed -n "$count p" /root/updatefile1.txt)  
 
 #  
 
 echo $f  
 
 #  
 
 if [ /home/$i != /home/$f ]  
 
 #  
 
 then  
 
 #  
 
 mv /home/$i /home/$f  
 
 #  
 
 fi  
 
 #  
 
 count=$(($count+1))  
 
 # done  
 
 # echo "重命名扩展名成功"  
 
 # }  
 
 # UpdateType csv txt 
 
 
 最后一题想了好久,终于写出来了,shell是真的阴间。 
 
 愉快的双休又来喽!