c高级day4shell脚本

7.3wc指令(word count)
wc 文件名
回显文件名,文件的行数,文件中单词和字符的个数,到终端
wc -w 文件名 ---->显示单词的个数
wc -l 文件名 ---->显示文件的行数
wc -c 文件名 ---->显示文件中字符的个数
7.4case···in
C语言中的switch···case
switch (参数)
{
    case 常量表达式1:
        执行语句;
        break;
    case 常量表达式2:
        执行语句;
        //break;   --->C语言中break可以不加,break的作用条吃醋switch···case语句
        ·····
    case 常量表达式n:
        执行语句;
        break;        
}

shell中的case···in语句
case $变量名 in
    常量1)
        语句块
        ;;
    常量2)
        语句块
        ;;
        ·····
    常量n)
        语句块
        ;;         #;;的作用类似于C中的switch···case
        #shell中;;除最后一条语句外,必须要加
    *)             #类似于C中的default,在shell中*会影响程序的执行
        语句块    
esac          

case···in语句中可以加什么样的常量表达式:
1):符合1的情况
[1-9]):符合1-9的情况
[1-9]|10):符合1-9或者10的情况    
7.5shell中的特殊字符----通配符
*:通配一个或多个任意字符
?:通配一个任意字符
[]:通配[]内的任一个字符 ----->可以使用在case···in语句中
[12345]:通配12345中的任一个字符
[1,2,345]:通配12345+,中的任一个字符,可以加,因为逗号可以做字符但是不能加空格
[1-4]:通配1-4中的任一个字符
[a-c]:通配a-c中任一个字符
[1-4abc]:通配1-4和abc中的任一个字符

练习:

1、输入学生成绩,判断等级,A[100,90),B[90,80),C[80,70),D[70,60)

#!/bin/bash 
read num
case $num in
    100|9[1-9])
        echo "A"
        ;;
    90|8[1-9])
        echo "B"
        ;;
    80|7[1-9])
        echo "C"
        ;;
    70|6[0-9])
        echo "D"
        ;;
    *)
        echo "不及格"
esac

2、终端输入年和月,判断这个月有多少天

#!/bin/bash
read -p "请输入年" year
echo ""
read -p "请输入月" mon
case $mon in
    [13578]|10|12)
        echo "31"
        ;;    #shell中;;不可以省略
    [469]|11)
        echo "30"
        ;;
    2)
        if test $((year%4)) -eq 0 && test $((year%100)) -ne 0 || test $((year%400)) -eq 0
        then
            echo "29"
        else
            echo "28"
        fi
esac

3、终端输入一个字符,判断是小写字母,大写字母,数字字符还是其他符号
shell中使用都是正则表达式,posix,[:lower:] [:upper:]

#!/bin/bash
read -p "请输入一个字符" c
case $c in
    [[:upper:]])
        echo "$c是一个大写字符"
        ;;
    [[:lower:]])
        echo "$c是一个小写字符"
        ;;  #除最后一个分支外;;一定要写
    [1-9])
        echo "$c是一个数字字符"
        ;;
    *)
        echo "其他字符"
esac

注意事项:

  • case···in不存在case击穿,要求,除了最后一个分支其余都要加;;
  • case···in语句中,表示通配所有情况,如果使用一定要放在最后,否则其他分支不能执行
  • case···in语句中,常量表达式,可以使用通配符和|
  • case···in语句,在判断变量的值,所以case后面,使用的是$变量名

八、shell中的循环语句

8.1while循环
while [ test表达式 ]
do
    语句块
done

练习:

1、求1-100的和

#!/bin/bash 
i=1   #循环变量
sum=0 #求和变量
while [ $i -le 100 ]  #条件
do
    ((sum+=i))  
    ((i++)) #循环变量自增
done
echo $sum

2、求100-1000的水仙花数

#!/bin/bash
i=100
while test $i -lt 1000
do
    a=$((i%10))    #求个位
    ((b=i%100/10)) #求十位
    ((c=i/100))    #求百位
    if [ $((a**3+b**3+c**3)) -eq $i ]
        #把幂次的结果相加,也是运算,需要使用(()),$[],let,expr任一个
    then
        echo $i
    fi
    ((i++))
done

3、打印直角三角形,终端输入行数
4、使用while循环,求数组中元素的和,要求:数组中元素,从命令行传参到脚本中

arr=($*)
i=${#arr[*]}
j=0
sum=0
while [ $j -lt $i ]
do
    ((sum+=${arr[j]}))
    ((j++))
done
echo $sum

5、输出1-100内,既是3的倍数也是7的倍数的数

i=1
while [ $i -le 100 ]
do
    if [ $((i%3)) -eq 0 -a $((i%7)) -eq 0 ]
    then
        echo $i
    fi
    ((i++))
done
*
**
***
****
····
8.2for循环
类似于C语言的格式
for ((表达式1;表达式2;表达式3))
do
    循环体
done

和C语言的执行逻辑相同,表达式1一般是初始化语句,表达式2是条件,表达式3就是步长


shell中for循环的格式
for 变量 in 字符串列表
do
    循环体
done

for i in aa bb cc dd
do
    echo $i
done
输出结果:aa  bb cc dd
执行逻辑:
    让循环变量,遍历被字符串列表中的每一个字符串赋值,赋值全部结束后,循环结束
    for循环的次数只和字符传列表有关

练习:

1、使用for循环,求1-10的和

#!/bin/bash
sum=0
for((i=1;i<=10;i++))
do
    ((sum+=i))
done
echo $sum

sum=0
#for i in {1..10}
for i in `seq 1 1 100`    
do
    ((sum+=i))
done
echo $sum
8.3for循环中使用连续列表的情况
1、seq 起始值 间隔值 终止值   ----->起始值和间隔值的默认值为1
在终端打印连续的序列
如果想要把seq放在for循环后面,`seq 1 1 100`
2、{1..100} ---->只能在for中使用,不是一个指令,可以直接使用
for i in {1..100}  ----->中间只能是..不能是...

练习:

1、定义一个稀疏数组,使用for循环,求数组中元素的和。(稀疏数组:下标不连续)
2、判断家目录下,普通文件的个数和目录文件的个数

#!/bin/bash
fcount=0
dcount=0
for filename in `ls ~`
do
    if [ -f ~/$filename ]   #一定要给文件加路径名
    then
        ((fcount++))
    elif [ -d ~/$filename ]
    then
        ((dcount++))
    fi
done
echo "普通文件的个数${fcount}"
echo "目录文件的个数${dcount}"

3、判断家目录下,c语言文件的个数

#!/bin/bash
sum=0
for filename in `ls ~/*.c`
do
    ((sum++))
done
echo $sum

4、输出下三角九九乘法表

#!/bin/bash
for i in `seq 9`
do
    #for ((j=1;j<=i;j++))
    for j in `seq $i`
    do
        printf "%d*%d=%-3d" $j $i $((i*j))
    done
    echo ""
done
8.4select···in语句
select 变量 in 选项列表
do
    语句块
done

执行逻辑:
执行select···in语句后,会在终端打印选项列表,需要选择选项的编号,
如果不输入直接回车,会再打印一遍选项列表,可以直接使用ctrl+c停止
1) aa
2) bb
3) cc
4) dd
#? 
8.5select···in和case···in结合使用
#!/bin/bash
select i in unix linux wins
do
    case $i in 
        unix)
            echo "现在打开的是unix系统"
            ;;
        linux)
            echo "现在打开的是linux系统"
            ;;
        wins)
            echo "现在打开的是wins系统"
            ;;
        *)
            echo "选择错误"
    esac
done

练习:

1、终端输入软件名,判断是否下载,如果y···,就下载该游戏,n····就打印不下载游戏。

#!/bin/bash
read -p "请输入一个游戏名" game
select i in Y YES y yes N NO n NO
do
    case $i in 
        Y|YES|y|yes)
            sudo apt-get install $game
            ;;
        N|NO|n|no)
            echo "不下载该游戏"
    esac
done
8.6辅助控制关键字

i)break

break n   退出n层循环
break   ---->跳出1层循环,n可以不写

ii)continue

continue n    退出n层本次循环
continue  ---->跳出1层循环,n可以不写
#!/bin/bash
for((i=1;i<3;i++))
do
    echo "第一层循环 i=$i*******************"
    echo 
    for j in `seq 1 1 2`
    do
        echo "第二层循环 j=$j------------------"
        echo 

        for k in {1..3}
        do
            echo "第三层循环 k=$k /"
            echo 

            if [ $k -eq 2 ]
            then
                echo "准备跳出3层本次循环"
                #break 2 
                continue 3
            fi

            echo "第三层循环 k=$k/"
            echo 
        done
        echo "第二层循环 j=$j------------------"
        echo 
    done
    echo "第一层循环 i=$i*******************"
    echo 
done

练习:

1、把九九乘法表,使用break做一遍

#!/bin/bash
for ((i=9;i>=1;i--))
do
    for j in `seq $i`
    do
        printf "%d*%d=%-3d" $j $i $((i*j))
    done
    echo
done

#!/bin/bash
for i in `seq 9`
do
    for j in `seq $i 1 9`
    do
        printf "%d*%d=%-3d" $i $j $((i*j))
    done
    echo 
done

#!/bin/bash
for i in `seq 9`   #外层循环,循环1-9
do
    for j in `seq 9`  #内层循环,循环1-9
    do
        if [ $j -gt $i ]
        then
            break
        fi
        printf "%d*%d=%-3d" $j $i $((i*j))
    done
    echo 
done

九、shell中的函数

9.1定义

定义函数时,建议加上function

function 函数名()
{
    语句块
    return 函数的返回值 ----->函数是否有返回值,根据函数体内是否有return决定
}

注意事项:
1、shell中定义函数的()不能放任何内容,函数是否有参数,根据调用函数时是否传参决定
2、定义函数时,可以加function也可以不加function,建议添加
3、函数是否有返回值,根据函数的实现决定
4、shell中函数仍然满足,先定义后使用的原则,但是函数的声明和定义不能分开    
9.2调用
C语言中:
    函数名(实参)
shell中:
    函数名 
 如果调用时,需要传参数:
    函数名  参数1  参数2  参数3   参数4 ····     
9.3获取外部参数
函数的外部传参,需要使用位置变量获取
${n} 
获取所有外部参数:$*
获取外部参数的个数:$#

函数的外部参数和脚本的外部参数是相互独立的
如果在脚本内使用位置变量${n},$*,$# ----->都是脚本的外部传参
如果在函数内使用位置变量${n},$*,$# ----->都是函数的外部传参

$0只能表示脚本名

练习:

1、写一个函数,求数组中元素的和,要求:数组通过参数传递给函数,函数要输出求和的结果

#!/bin/bash
function sum()
{
    s=0
    for i in $*   #$*获取到所有的外部参数
    do
        ((s+=i))
    done
    echo $s
}

arr=([0]=90 [5]=100 [9]=7 )
sum ${arr[*]}
9.4函数的返回值
1、shell中只能返回0-255的数
2、shell中的返回值,使用$?接收   ----->$?的本质是上一条指令的返回值
#!/bin/bash
function sum()
{
    s=0
    for i in $*   #$*获取到所有的外部参数
    do
        ((s+=i))
    done
    return $s
}

arr=([0]=90 [5]=100 [9]=7 )
sum ${arr[*]}
echo 9
var=$?   #使用$?接受函数的返回值的指令,必须紧跟着函数调用的指令
#由于var=$?,核函数调用之间,隔了一条指令,所以获取到的结果是0
echo $var
9.5函数没有返回值但想接收结果
1、函数没有返回值,但是仍需要函数的结果
2、函数的返回值,大于255

可以在函数内部写一条输出语句,使用命令置换符,接收函数的结果
#!/bin/bash
function sum()
{
    s=0
    for i in $*   #$*获取到所有的外部参数
    do
        ((s+=i))
    done
    return $s
}

arr=([0]=90 [5]=100 [9]=7 )
sum ${arr[*]}
echo 9
var=$?   #使用$?接受函数的返回值的指令,必须紧跟着函数调用的指令
#由于var=$?,核函数调用之间,隔了一条指令,所以获取到的结果是0
echo $var
9.6local

local的作用:在函数内定义局部变量

在shell脚本中,所有的变量都是全局变量,只要被赋值后,任意位置都可以访问

#!/bin/bash
function fun()
{
    local sum=100   #如果不加local函数外可以访问sum
    echo "函数内$sum"
    unset sum       #unset可以清空local的变量
    echo "清空后$sum"
}

fun
echo $sum

写一个函数,获取用户的uid和gid并使用变量接收

#!/bin/bash 
uid=0
gid=0
function getUidAndGid()
{
	uid=`id -u`
	gid=`id -g`
	echo $uid 
	echo $gid
	infoArr=($uid $gid)
	return $infoArr
}
getUidAndGid 
arr=$?
echo ${arr[*]}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值