shell学习笔记之七(循环)
循环
shell中的循环主要有for,while,untile,select
for
1、列表for循环
for VARIABLE in (list)
do
command
done
例:循环打印john喜欢的水果
for fruit in apple orange banana pear
do
echo "$fruit is John‘s favorite"
done
echo "No more fruits."
注意:
in里面可以是任意命令的标准输出
如:
fruits="apple orange banana pear"
seq 1 2 100 #产生1到100的奇数数列
ls
1..5 #表示1 2 3 4 5
#!/bin/bash
echo ‘变量作为in的参数‘
fruits="apple orange pear"
for fruit in ${fruits}
do
echo $fruit
done
echo "序列作为in的参数"
for var in 1 2 3 4 5
do
echo $var
done
echo "seq产生的序列作为in的参数"
#declare -i total=0
total=0
for var in $(seq 1 2 100)
do
#total+=$var
#(( total += var )) #注意算数运算的写法,一共三种写法都可以实现赋值
let "total+=var"
done
echo "1+3+5+...+99 is $total"
echo "ls的结果作为in的参数"
for var in $(ls)
do
ls -l $var
done
2、不带列表的for循环
for variable
do
command
done
注意:使用不带列表的for,需要在运行脚本时通过参数的方式给for传递变量值
#for.sh
#!/bin/bash
for var
do
echo $var
done
# . ./for.sh 1 2 3
可读性差,可以使用$@实现上面的功能
改进:
#!/bin/bash
for var in $@
do
echo $var
done
3、类Cfor循环
for ((expression ;expression2; expression3))
do
command
done
例:
#!/bin/bash
for (( i=0; i<10; i++ )) #这里没有什么空格的要求,为了美观,使用空格
do
echo -n "$i "
done
4、for的无限循环
for((;1;))
do
echo
done
while
while expression
do
command
done
例:
1、#输出1到10的数字序列
#!/bin/bash
declare -i count=0
while [[ $count -lt 10 ]]
do
echo "$count"
count+=1
done
2、#求1-100之和
#求1-100之间奇数之和
#!/bin/bash
declare -i sum01=0
declare -i sum02=0
declare -i i=1
declare -i j=1
while [[ i -le 100 ]]
do
sum01+=i;
j=i%2;
#if [[ $(( i%2 )) -ne 0 ]];then
if [[ j -ne 0 ]];then
sum02+=i;
fi
((i++));#这里不可一写$((i++))
done
echo $sum01
echo $sum02
3、#猜数字
#!/bin/bash
num=8
echo "Input a number in 1 to 10:"
#体会read的用法
while read guass
do
if [[ $guass -eq $num ]];then
echo "Right."
break
else
echo "Wrong.Try Again"
fi
done
4、按行读取文件
cat student_info.txt
John 30 Boy
Sue 28 Girl
Wang 25 Boy
Xu 23 Girl
解法一:
#!/bin/bash
while read line
do
name=`echo $line | cut -d ‘ ‘ -f1` #echo输出line之后Tab会变成空格,所以使用cut的时候需要指定分割符(-d ‘ ‘)
age=`echo $line | cut -d ‘ ‘ -f2` #也可以使用awk awk ‘{print $n}‘,awk的分割符是空格(‘ ‘)或Tab
sex=`echo $line | cut -d ‘ ‘ -f3`
echo "My name is $name,I‘m $age years old,I‘m a $sex"
done < student_info.txt
注意:整个思路是清晰的,重点是怎么读取文件,选用什么命令处理行。比较而言,脚本比编辑一个高级语言程序要简洁很多
解法二:
#!/bin/bash
cat student_info.txt | while read line
do
name=`echo $line | cut -d ‘ ‘ -f1`
age=`echo $line | cut -d ‘ ‘ -f2`
sex=`echo $line | cut -d ‘ ‘ -f3`
echo "My name is $name,I‘m $age years old,I‘m a $sex"
done
两种解法功能相同,但是有细微差别。使用重定向的while只会产生一个shell,而使用管道的脚本在运行时会产生3个shell,第一个shell是cat(运行很快,导致无法使用ps命令抓到),第二个shell是管道,第三个shell是while
5、无限循环
#方法一
while ((1))
do
command
done
#方法二
while true
do
command
done
#方法三
while :
do
command
done
例:检测系统进程,
#!/bin/bash
while true
do
ATD_STATUS=`service atd status | grep running`
if [[ -z "$ATD_STATUS" ]];then
echo "ATD is stopped , try to restart."
service atd restart #在脚本中,如果不需要命令的返回值,则直接写命令即可,而不需要用$()命令替换
else
echo "ATD is running,wait 5 sec until next check"
fi
sleep 5 #延迟函数,单位是秒(s)
done
until
结构:
until expression
do
command
done
描述:
运行前测试,测试结果为false时继续执行,为true时退出
例:
#使用until计算1到100的和以及1-100的奇数和
#!/bin/bash
declare -i sum01=0
declare -i sum02=0
declare -i i=0
until [[ i -gt 100 ]]
do
sum01+=i
if [[ $[i%2] -ne 0 ]];then
sum02+=i
fi
((i++));
done
echo "sum01=$sum01"
echo "sum02=$sum02"
until的无限循环
until ((0))
do
command
done
until false
do
command
done
select循环
结构:
select Menu in (list)
do
command
done
描述:
菜单扩展循环方式,语法和带列表的for循环非常类似
例:
1、判断用户的选择
#!/bin/bash
echo "Which car do you prefer?"
select car in Benz Audi VolksWagen
do
break #注意这个break,没有这个会一直处于选择状态
done
echo "You chose $car"
注解:select有判断用户输入的功能,所以select经常和case语句合并使用,
2、联合使用select和case
#!/bin/bash
select var in Mon Tue Wed Thu Fri Sat Sun
do
case $var in #case是不需要break语句的
Mon)
echo "Today is Monday"
break ;;
Tue)
echo "Today is Tuesday"
break;;
Wed)
echo "Today is Wednesday"
break ;;
Thu)
echo "Today is Thursday"
break ;;
Fri)
echo "Today is Friday"
break ;;
Sat|Sun)
echo "You can have a rest day"
break;;
*)
echo "Unknown input.Try again" ;;
esac
done
嵌套循环
例:打印九九乘法表
#!/bin/bash
declare -i i=1;
declare -i j=1;
declare -i k=0
for (( i = 1; i <= 9; i++ ))
do
for (( j = 1; j <= i; j++ ))
do
k=$i+$j
#let "k=i+j"
echo -ne $j"*"$i"="$k"\t"
#echo -ne $j"*"$i"="$(($i+$j))"\t"
#echo -ne $j"*"$i"="$[$j*$i]"\t"
#这里看到了多种表达式求值
done
echo
done
注意:
1、for的类C写法,不需要$符号,也不需要使用-le之类的
2、echo输出制表符,需要使用-e参数,这表示有转义字符时转义。没有-e会原样输出而不解释转义字符
3、表达式求值
4、自行改编成其他循环版本的九九乘法表
扩展:使用sed和awk输出九九乘法表
#!/bin/bash
seq 9 |sed "H;g"|awk -v RS="" ‘{
for(i=1;i<=NF;i++){
j=i*NR;
printf("%d*%d=%d\t",i,NR,i*NR);
}
printf("\n");
}‘
循环控制
break
continue
不做详细介绍,跟高级语言一样,唯一的区别是break,continue后面可以接数字,表示跳出嵌套层数,和Java中的标签类似。
例:打印素数
解法一:
#!/bin/bash
declare -i i=1
declare -i j=2
for (( i = 1; i < 100 ; i++ ))
do
for (( j = 2; j < i ;j++ ))
do
if ! (($i%$j));then #注意! 和(())扩展运算之间有空格
break;
fi
done
if [[ $j -eq $i ]];then
echo -ne "$i\t"
fi
done
echo
解法二:
#!/bin/bash
declare -i i=1
declare -i j=2
for (( i = 1; i < 100 ; i++ ))
do
for (( j = 2; j < i ;j++ ))
do
if ! (($i%$j));then #注意! 和(())扩展运算之间有空格
continue 2; #continue后面的数字表示跳出的嵌套数
fi
done
if [[ $j -eq $i ]];then
echo -ne "$i\t"
fi
done
echo
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。