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[*]}