循环执行结构:
循环结构包括两个环节;
1.进入循环的条件:
在符合要求或满足条件时才开始循环;
2.退出循环的条件:
达到某个要求或符合某个条件时需要结束或终止循环的执行;
for循环:
1.遍历列表的循环:
为列表中的每个成员执行命令。
for 名称 [in 词语 ... ] ; do 命令; done
建议在脚本中的书写格式:
for VAR_NAME in LIST ; do
循环体
done
或
for VAR_NAME in LIST
do
循环体
done
注意:
VAR_NAME:任意指定的变量名称,变量的值是从LIST中遍历获取的各个元素;
LIST:for循环需要变量的列表;可以通过以下方式生成列表:
1.直接给出列表;
2.纯整数列表;
1)花括号展开:
[[email protected] ~]# echo {1..10}
1 2 3 4 5 6 7 8 9 10
{FIRST,SECOND,THIRD,...,LAST}
[[email protected] ~]# echo {1,2,3,4,5}
1 2 3 4 5
2)seq命令
seq [OPTION]... LAST :给出一个数字,默认从1到指定数字,默认是递增顺序;
[[email protected] ~]# seq 5
1
2
3
4
5
seq [OPTION]... FIRST LAST :给出开始的数字,之后递增到指定的数字,默认递增;
[[email protected] ~]# seq 2 5
2
3
4
5
seq [OPTION]... FIRST INCREMENT LAST :给出开始的数字,中间是递增(可正可负)间隔
[[email protected] ~]# seq 2 2 10
2
4
6
8
10
[[email protected] ~]# seq 10 -2 2
10
8
6
4
2
3)花括号展开:
{FIRST...LAST}(字母也可以)
[[email protected] ~]# echo {a..z}
a b c d e f g h i j k l m n o p q r s t u v w x y z
[[email protected] ~]# echo {A..Z}
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
4)命令的执行结果:
ls /etc
grep /PATH/TO/SOMEFILE
5) GLOBBING(通配符)
6)某些特殊变量的值:
$*,[email protected]
循环体:
一般来说,循环体中应该包括能够用到VAR_NAME变量的值的命令或命令的组合;如果循环体中的命令并没有用到VAR_NAME变量的值的话,列表元素个数 就是此次for循环的次数;
例子:
使用for循环写一个脚本,计算1到100的数字之和;
#!/bin/bash
#
declare -i SUM=0
for I in {1..100} ;do
#let SUM+=$I
SUM=$[SUM+I]
done
echo "The summary is: $SUM"
总结奇数的和以及偶数的和:
#!/bin/bash
#
declare -i SUM=0
for I in {1..100..2} ;do
#let SUM+=$I
SUM=$[SUM+I]
done
echo "The summary is: $SUM"
#!/bin/bash
#
declare -i SUM=0
for I in {seq 0 2 100} ;do
#let SUM+=$I
SUM=$[SUM+I]
done
echo "The summary is: $SUM"
写一个脚本,能够通过-a或-d选项添加或删除一个或多个用户:
#!/bin/bash
#
if [ $# -lt 2 ];then
echo "Make sure more than TWO arguments."
exit 6
fi
if [ $1 == '-a' ];then
for I in "[email protected]" ;do
if ! $I &> /dev/null;then
useradd $I &> /dev/null
echo $I | passwd --stdin $I $> /dev/null
echo "User $I created successfully and changed it's password it's username."
else
echo "User $I exists already."
fi
done
elif [ $1 == '-d' ]; then
for J in "[email protected]" ;do
if $J &> /dev/null;then
userdel -r $J &> /dev/null
echo "User $J deleted already."
else
echo "User $J is not exist yet."
fi
done
else
echo "Usage: $(basename $0) {-a UNAME1 [UNAME2 ...] | -d UNAME1 [UNMAE2 ...]}"
exit 5
fi
for循环总结:
1.进入循环的条件:LIST中尚有未被取尽的元素;
2.退出循环的条件:LIST中的元素被取尽;
3.for循环几乎不会出现死循环;
4.在执行循环的过程中,需要将整个LIST载入内存,因此对于大列表来说,可能会消耗较多的内存及CPU资源;
计算指定范围内自然数的和:
#!/bin/bash
#
#declare命令声明SUM初始值为0
declare -i SUM=0
#read命令与用户进行交互
read -p "Please input TWO integer: " I1 I2
#设置两个数I1和I2的值类型
if [[ $I1 =~ [^[:digit:]] ]];then
echo "$I1 must is an integer."
exit 7
fi
if [[ $I2 =~ [^[:digit:]] ]];then
echo "$I2 must is an integer."
exit 7
fi
#利用if选择执行结构和for循环进行嵌套
if [ $I1 -gt $I2 ];then
for I in {seq $I2 $I1} ;do
SUM=$[SUM+I]
done
echo "The summary is: $SUM"
else
for I in {seq $I1 $I2} ;do
SUM=$[SUM+I]
done
echo "The summary is: $SUM"
fi
写一个脚本,打印有“*”组成的倒置的等腰三角形:
********* 1行,0个空白字符,9个*
******* 2行,1个空白字符,7个*
***** 3行,2个空白字符,5个*
*** 4行,3个空白字符,3个*
* 5行,4个空白字符,1个*
N行,N-1个空白字符,2*(总行数-当前行号)+1个*
#!/bin/bash
#
if [ $# -ne 1 ];then
echo "Usage: $(basename $0) INTEGER."
exit 5
fi
if [[ $1 =~ [^[:digit:]] ]];then
echo "Usage: $(basename $0) INTEGER."
exit 5
fi
LINENUM=$1
for I in $(seq $LINENUM);do
for J in $(seq $[I-1]) ;do
echo -n " "
done
for K in $(seq $[2*(LINENUM-I)+1]); do
echo -n "*"
done
echo
done
打印九九乘法表:
第一行:1个
第二行:2个
...
第九行:9个
第一种方法:
#!/bin/bash
#
for I in {1..9} ;do
for J in $(seq $I);do
echo -ne "$J x $I = $[I*J]\t"
done
echo
done
第二种方法:
控制变量实现for循环--
#!/bin/bash
#
for (( I=1 ; I<=100 ; I++)) ; do
for (( J=1 ; J<=I ; J++)) ; do
echo -ne "$J x $I = $[I*J]\t"
done
echo
done
以上两个例子,均使用for循环的嵌套;往往需要两层的循环嵌套才能打印出平面效果;外层的for循环,负责控制行数输出;内层的for循环,负责控制每一行中各个列的输出;
2.通过控制变量实现for循环:
for(( exp1; exp2; exp3));do COMMANDS; done
可以在脚本中写成如下格式:
for(( exp1; exp2; exp3));do
COMMANDS
done
exp1:表达式1,为指定的变量赋初始值
exp2:表达式2,此次循环的退出条件
exp3:表达式3,指定的变量的值的变化规律
计算1到100的自然数的和:
#!/bin/bash
#
for (( I=1 ; I<=100 ; I++));do
let SUM+=$I
done
echo "The summary is: $SUM"