流程控制循环语句

一、流程控制语句

流程判断1

image

if [ condition ];then
	command
	command
fi

[ 条件 ] && command

流程判断2

image

if [ condition ];then
	command1
else
	command2
fi

[ 条件 ] && command1 || command2

流程判断3

image

if [ condition1 ];then
	command1  结束
elif [ condition2 ];then
	command2   结束
else
	command3
fi
注释:
如果条件1满足,执行命令1后结束;如果条件1不满足,再看条件2,如果条件2满足执行命令2后结束;如果条件1和条件2都不满足执行命令3结束.

流程判断4

image

if [ condition1 ];then
	command1
	if [ condition2 ];then
		command2
	fi
else
	if [ condition3 ];then
		command3
	elif [ condition4 ];then
		command4
	else
		command5
	fi
fi
注释:
如果条件1满足,执行命令1;如果条件2也满足执行命令2,如果不满足就只执行命令1结束;
如果条件1不满足,不看条件2;直接看条件3,如果条件3满足执行命令3;如果不满足则看条件4,如果条件4满足执行命令4;否则执行命令5

二、循环语句

循环控制:
循环体:do....done之间的内容
- continue:继续;表示跳过本次循环体do和done之间的continue后面的代码不执行,重新开始下一次循环
- break:打断;马上中断循环,执行循环体外的代码
- exit:表示直接退出脚本程序
exit可以在shell中任意地方使用,表示程序直接退出,continue和break仅仅用于循环的for和while使用
- shell:使位置参数向左移动,默认移动1位,可以使用shift n来使其移动n位   

1、for循环

1.1 列表循环

列表for循环:用于将一组命令执行已知的次数

for variable in {list}
     do
          command
          command
          …
     done
或者
for variable in a b c
     do
         command
         command
     done

1.2 不带列表循环

不带列表的for循环执行时由用户指定参数和参数的个数

for variable
    do
        command
        command
        …
   done

1.3 类C风格的for循环

for(( expr1;expr2;expr3 ))
    do
        command
        command
        …
   done
for (( i=1;i<=5;i++))
    do
        echo $i
   done

expr1:定义变量并赋初值
expr2:决定是否进行循环(条件)
expr3:决定循环变量如何改变,决定循环什么时候退出

练习:局域网内,把能ping通的IP和不能ping通的IP分类,并保存到两个文本文件里。

以10.1.1.1~10.1.1.10为例
#!/bin/bash
#定义变量
ip=10.1.1
#循环去ping主机的IP
for ((i=1;i<=10;i++))
do
	ping -c3 $ip.$i &>/dev/null
	if [ $? -eq 0 ];then
		echo "$ip.$i is ok" >> /tmp/ip_up.txt
	else
		echo "$ip.$i is down" >> /tmp/ip_down.txt
	fi
	或者
	[ $? -eq 0 ] && echo "$ip.$i is ok" >> /tmp/ip_up.txt || echo "$ip.$i is down" >> /tmp/ip_down.txt
done

并行执行:
{程序}&表示将程序放到后台并行执行,如果需要等待程序执行完毕再进行下面内容,需要加wait
#!/bin/bash
#定义变量
ip=10.1.1
#循环去ping主机的IP
for ((i=1;i<=10;i++))
do
{

        ping -c1 $ip.$i &>/dev/null
        if [ $? -eq 0 ];then
                echo "$ip.$i is ok" >> /tmp/ip_up.txt
        else
                echo "$ip.$i is down" >> /tmp/ip_down.txt
        fi
}&
done
wait
echo "ip is ok...."

2. while循环

条件为真就进入循环;条件为假就退出循环

while 表达式
  do
     command
     command
     ...
 done

举例说明

用while循环计算1-50的偶数和
#!/bin/bash
#定义变量
sum=0
i=2
#循环打印1-50的偶数和并且计算后重新赋值给sum
while [ $i -le 50 ]
do
	let sum=sum+i
	let i+=2
done
#打印sum的值
echo "1-50的偶数和为:$sum"

3.until循环

条件为假就进入循环;条件为真就退出循环

until 表达式
do
	command
	command
	...
done

举例说明

使用until语句批量创建10个用户,要求stu1—stu5用户的UID分别为1001—1005;stu6~stu10用户的家目录分别在/rhome/stu6—/rhome/stu10
#!/bin/bash
i=1
until [ $i -gt 10 ]
do
	if [ $i -le 5 ];then
		useradd -u $[1000+$i] stu$i && echo 123|passwd --stdin stu$i
	else
		[ ! -d /rhome ] && mkdir /rhome
		useradd -d /rhome/stu$i stu$i && echo 123|passwd --stdin stu$i		
	fi
let i++
done

三、随机数

bash默认有一个$RANDOM的变量,默认是0~32767。
使用set |grep RANDOM 查看上一次产生的随机数
echo $RANDOM

产生0~1之间的随机数
echo $[$RANDOM%2]

产生0~2之间的随机数
echo $[$RANDOM%3]

产生0~3之间的随机数
echo $[$RANDOM%4]
。。。。
产生0~9内的随机数
echo $[$RANDOM%10]

产生0~100内的随机数
echo $[$RANDOM%101]

产生50-100之内的随机数
echo $[$RANDOM%51+50]

产生三位数的随机数
echo $[$RANDOM%900+100]

举例说明

产生一个phonenum.txt文件,随机产生以139开头的手机号1000个,每个一行。
#!/bin/bash
# random phonenum
# 循环1000次产生电话号码并保存到文件
for i in {1..1000}
do
	n1=$[RANDOM%10]
	n2=$[RANDOM%10]
	n3=$[RANDOM%10]
	n4=$[RANDOM%10]
	n5=$[RANDOM%10]
	n6=$[RANDOM%10]
	n7=$[RANDOM%10]
	n8=$[RANDOM%10]
	echo "139$n1$n2$n3$n4$n5$n6$n7$n8" >> phonenum.txt
done

在上面的1000个手机号里抽奖5个幸运观众,显示出这5个幸运观众。但只显示头3个数和尾号的4个数,中间的都用*代替
#!/bin/bash
#定义变量
phone=/shell04/phonenum.txt
for ((i=1;i<=5;i++))
do
	#定位幸运观众所在行号
	line=`wc -l $phone |cut -d' ' -f1`
	luck_line=$[RANDOM%$line+1]
	#取出幸运观众所在行的电话号码
	luck_num=`head -$luck_line $phone|tail -1`
	#显示到屏幕
	echo "139****${luck_num:7:4}"
	echo $luck_num >> luck.txt
	#删除已经被抽取的幸运观众号码
	sed -i "/$luck_num/d" $phone
done

四、case语句

case var in             定义变量;var代表是变量名
pattern 1)              模式1;用 | 分割多个模式,相当于or
    command1            需要执行的语句
    ;;                  两个分号代表命令结束
pattern 2)
    command2
    ;;
pattern 3)
    command3
    ;;
	*)              default,不满足以上模式,默认执行*)下面的语句
    command4
    ;;
esac			esac表示case语句结束

举例

#!/bin/bash
#打印菜单
menu(){
cat <<-END
	h	显示命令帮助
	f	显示磁盘分区
	d	显示磁盘挂载
	m	查看内存使用
	u	查看系统负载
	q	退出程序
	END
}
menu
while true
do
read -p "请输入你的操作[h for help]:" var1
case $var1 in
	h)
	menu
	;;
	f)
	read -p "请输入你要查看的设备名字[/dev/sdb]:" var2
	case $var2 in
		/dev/sda)
		fdisk -l /dev/sda
		;;
		/dev/sdb)
		fdisk -l /dev/sdb
		;;
	esac
	;;
	d)
	lsblk
	;;
	m)
	free -m
	;;
	u)
	uptime
	;;
	q)
	exit
	;;
esac
done

五、正则表达式

1.正则表达式的定义

正则表达式(Regular Expression、regex或regexp,缩写为RE),也译为正规表示法、常规表示法,是一种字符模式,用于在查找过程中匹配指定的字符。

2.第一类正则

元字符:指那些在正则表达式中具有特殊意义的专用字符,如:点(.) 星(*) 问号(?)等

前导字符:即位于元字符前面的字符 abc* aooo.

(1).		任意单个字符,除了换行符 
(2)*		前导字符出现0次或连续多次  ab*能匹配“a”,“ab”以及“abb”,但是不匹配“cb”
(3).*		任意长度的字符  ab.*  ab123 abbb abab
(4)^		行的开头
(5)$		行的结尾
(6)^$		空行
(7)[]		匹配指定字符组内的任一单个字符   [abc]
(8)[^]		匹配不在指定字符组内的任一字符 	[^abc]
(9)^[]		匹配以指定字符组内的任一字符开头   ^[abc]
(10)^[^]	匹配不以指定字符组内的任一字符开头  ^[^abc] 
(11)\<		取单词的头
(12)\>		取单词的尾
(13)\<\>	精确匹配符号 	grep -w 'xxx'
(14)\{n\}	匹配前导字符连续出现n次    go\{2\}   google  gooogle
(15)\{n,\}	匹配前导字符至少出现n次 
(16)\{n,m\}	匹配前导字符出现n次与m次之间 
 (17) \(strings\)	保存被匹配的字符
 将192.168.0.254 换成 192.168.1.254
 # sed -n 's#\(192\.168\)\.0\.254#\1\.1\.254#p'
 找出含有192.168的行,同时保留192.168并标记为标签1,之后可以使用\1来引用它。最多可以定义9个标签,从左边开始编号,最左边的是第一个。
 (18)Perl内置正则:
 \d      匹配数字  [0-9]
 \w      匹配字母数字下划线[a-zA-Z0-9_]
 \s      匹配空格、制表符、换页符[\t\r\n]
 #grep -P '\d' test.txt
 #grep -P '\w' test.txt
 #grep -P '\s' test.txt

3.扩展类的正则表达式 grep -E 或则 egrep

扩展正则表达式元字符
+		匹配一个或多个前导字符		bo+	boo bo
?		匹配零个或一个前导字符		bo?	b bo
a|b		匹配a或b
()		组字符	   hello myself yourself     (my|your)self
{n}		前导字符重复n次			\{n\}
{n,}		前导字符重复至少n次	  \{n,\}
{n,m}		前导字符重复n到m次		\{n,m\}
 # grep '[0-9]\{2\}\.[0-9]\{1\}\.[0-9]\{1\}\.[0-9]\{1\}' 1.txt
 10.1.1.1
 # grep -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' 1.txt
 10.1.1.1
 # grep -E '([0-9]{1,3}\.){3}[0-9]{1,3}' 1.txt
 10.1.1.1

4.第二类正则

表达式 功能 示例
[:alnum:] 字母与数字字符 [[:alnum:]]+
[:alpha:] 字母字符(包括大小写字母) [[:alpha:]]
[:blank:] 空格与制表符 [[:blank:]]*
[:digit:] 数字 [[:digit:]]?
[:lower:] 小写字母 [[:lower:]]
[:upper:] 大写字母 [[:upper:]]+
[:punct:] 标点符号 [[:punct:]]
[:space:] 包括换行符,回车等在内的所有空白 [[:space:]]+

正则总结

元字符 字符说明 示例
* 前导字符出现0次或者连续多次 ab* abbbb
. 除了换行符以外,任意单个字符 ab. ab8 abu
.* 任意长度的字符 ab.* adfdfdf
[] 括号里的任意单个字符或一组单个字符 [abc][0-9][a-z]
[^] 不匹配括号里的任意单个字符或一组单个字符 [^abc]
[1] 匹配以括号里的任意单个字符开头 [2]
^[^] 不匹配以括号里的任意单个字符开头
^ 行的开头 ^root
$ 行的结尾 bash$
^$ 空行
\{n\}和 前导字符连续出现n次 [0-9]\
\{n,\}和 前导字符至少出现n次 [a-z]
\{n,m\}和 前导字符连续出现n-m次 go
\<\> 精确匹配单词 \<hello\>
\(\) 保留匹配到的字符 \(hello\)
+ 前导字符出现1次或者多次 [0-9]+
? 前导字符出现0次或者1次 go?
| ^root|^ftp
() 组字符 (hello|world)123
\d perl内置正则 grep -P \d+
\w 匹配字母数字下划线

  1. ↩︎

  2. abc ↩︎

posted @ 2023-05-23 15:46  村尚chun叔  阅读(25)  评论(0编辑  收藏  举报