博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
循环与分支
阅读量:6109 次
发布时间:2019-06-21

本文共 4686 字,大约阅读时间需要 15 分钟。

hot3.png

1. 循环

for循环

for arg in [list]  这是一个基本的循环结构. 它与C语言中的for循环结构有很大的不同.
for arg in [list]
do
command(s)...
done

for arg in "$var1" "$var2" "$var3" ... "$varN" 在[list]中的参数加上双引号是为了阻止单词分割.

list中的参数允许包含通配符. 如果do和for想在同一行中出现, 那么在它们之间需要添加一个分号.

for planet in Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune Plutodo  echo $planet  # 每个行星都被单独打印在一行上.donefor planet in "Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune Pluto"   
do  echo $planet #所有的行星名称都打印在同一行上.# 整个'list'都被双引号封成了一个变量.done

每个[list]中的元素都可能包含多个参数. 在处理参数组时, 这是非常有用的. 在这种情况下, 使用set命令(参见 例子 11-15)来强制解析每个[list]中的元素, 并且将每个解析出来的部分都分配到一个位置参数中.

#!/bin/bash

# 用行星距太阳的距离来分配行星的名字.
 for planet in "Mercury 36" "Venus 67" "Earth 93" "Mars 142"  "Jupiter 483"
do
 set -- $planet # 解析变量"planet"并且设置位置参数.  "--" 将防止$planet为空, 或者是以一个破折号开头.
   # 可能需要保存原始的位置参数, 因为它们被覆盖了.# 一种方法就是使用数组.
  # original_params=("$@")
echo "$1 $2,000,000 miles from the sun"  #-------two tabs---把后边的0和2连接起来
done

可以将一个变量放在for循环的[list]位置上.

FILES="/usr/sbin/accept/usr/sbin/pwck/usr/sbin/chroot/usr/bin/fakefile/sbin/badblocks/sbin/ypbind" # 这是你所关心的文件列表. for file in $FILES do         if [ ! -e "$file" ] # 检查文件是否存在.         then               echo "$file does not exist."; echo               continue # 继续下一个.          fi          ls -l $file | awk '{ print $9 " file size: " $5 }' # 打印两个域.          whatis `basename $file` # 文件信息. 注意whatis数据库需要提前建立好.done

如果在for循环的[list]中有通配符 (*和?), 那么将会发生通配(globbing), 也就是文件名扩展.

 for file in [jx]*

 do
  rm -f $file # 只删除当前目录下以"j"或"x"开头的文件.
  echo "Removed file \"$file\"".
 done

在一个for循环中忽略in [list]部分的话, 将会使循环操作$@ -- 从命令行传递给脚本的位置参数. 一个非常好的例子

for ado echo -n "$a "  # 省略'in list'部分, 因此循环将会操作'$@'(包括空白的命令行参数列表)done
也可以使用命令替换 来产生for循环的[list]. NUMBERS="9 7 3 8 37.53" for number in `echo $NUMBERS` for word in $( strings "$2" | grep "$1" ) 列出系统上的所有用户 PASSWORD_FILE=/etc/passwd for name in $(awk 'BEGIN{FS=":"}{print $1}' < "$PASSWORD_FILE" ) 在目录的所有文件中查找源字串 directory=/usr/bin/ ; fstring="Free Software Foundation" # 查看哪个文件中包含FSF. for file in $( find $directory -type f -name '*' | sort ) do   strings -f $file | grep "$fstring" | sed -e "s%$directory%%" done 列出目录中所有的符号链接文件. directory=${1-`pwd`} for file in "$( find $directory -type l )" # -type l = 符号链接 do   echo "$file" done | sort  >> "$OUTFILE"          # 否则的话, 列出的文件都是未经排序的. 重定向到一个文件中. for file in $(ls $2.0*) # 在变量列表中使用通配符 有一种非常像C语言for循环的语法形式. 需要使用(()).例 for ((a=1, b=1; a <= LIMIT ; a++, b++)) # 逗号将同时进行两条操作. do   echo -n "$a-$b " done exit $?
while

  这种结构在循环的开头判断条件是否满足, 如果条件一直满足, 那么就一直循环下去 (返回0作为退出状态码). 与for循环的区别是, while循环更适合在循环次数未知的情况下使用.

while [condition]

do
  command...
done

while [condition] ; do  #与for循环一样, 如果想把do和条件判断放到同一行上的话, 还是需要一个分号。

一个while循环可以有多个判断条件. 但是只有最后一个才能够决定是否能够退出循环

 

while echo "previous-variable = $previous"

    previous=$var1
    [ "$var1" != end ]

do...done

 

与for循环一样, while循环也可以通过(())来使用C风格的语法

((a = 1)) # a=1 # 双圆括号允许赋值两边的空格, 就像C语言一样.

while (( a <= LIMIT )) # 双圆括号, 变量前边没有"$".
do
  echo -n "$a "
  ((a += 1)) # let "a+=1"

done 

while循环的stdin可以使用<来重定向到一个文件. while循环的stdin支持管道.

until

这个结构在循环的顶部判断条件, 并且如果条件一直为false, 那么就一直循环下去. (与while循环相反).

until [condition-is-true]

do
  command...
done

注意, until循环的条件判断在循环的顶部, 这与某些编程语言是不同的.

until [condition-is-true] ; do 放在同一行里,需要使用分号.

嵌套循环: 在一个循环中还有一个循环, 内部循环在外部循环体中

循环控制

影响循环行为的命令 break, continue : break命令用来跳出循环, 而continue命令只会跳过本次循环, 忽略本次循环剩余的代码, 进入循环的下一次迭代.

continue命令也可以象break命令一样带一个参数. 一个不带参数的continue命令只会去掉本次循环的剩余代码. 而continue N将会把N层循环的剩余代码都去掉, 但是循环的次数不变.

[ -r .Iso.$beta ] && continue[ -r .lock.$beta ] && sleep 10 && continue

 

测试与分支(case与select结构)

case (in) / esac , 在shell中的case结构与C/C++中的switch结构是相同的,它的作用和多个if/then/else语句的作用相同。

case "$variable" in

$condition1" )
TT CLASS="REPLACEABLE" >command...
;
$condition2" )
TT CLASS="REPLACEABLE" >command...
;
esac

对变量使用""并不是强制的, 因为不会发生单词分割.

每句测试行, 都以右小括号)来结尾.

每个条件判断语句块都以一对分号结尾 ;;

case块以esac (case的反向拼写)结尾.

case结构也可以过滤通配(globbing)模式的字符串.

case $( arch ) in                  i386* ) echo "80386-based machine";;  i486 ) echo "80486-based machine";;  i586 ) echo "Pentium-based machine";;  i686 ) echo "Pentium2+-based machine";;  *    ) echo "Other type of machine";;esac
case "$Keypress" in    [[:lower:]] ) echo "Lowercase letter";;    [[:upper:]] ) echo "Uppercase letter";;    [0-9] ) echo "Digit";;    * ) echo "Punctuation, whitespace, or other";;esac #  允许字符串的范围出现在[中括号]中, #+ 或者出现在POSIX风格的[[双中括号中.while [ $# -gt 0 ]; do # 直到你用完所有的参数. . .   case "$1" in     -d|--debug)# 是"-d" 或"--debug" 参数?       DEBUG=1;;     -c|--conf)       CONFFILE="$2"       shift       if [ ! -f $CONFFILE ]; then        echo "Error: Supplied file doesn't exist!"        exit $E_CONFFILE # 错误: 文件未发现.       fi      ;;   esac shift # 检查剩余的参数. done

 

 

转载于:https://my.oschina.net/flyxiang/blog/343713

你可能感兴趣的文章
Android扩展 - 拍照篇(Camera)
查看>>
JAVA数组的定义及用法
查看>>
充分利用HTML标签元素 – 简单的xtyle前端框架
查看>>
设计模式(十一):FACADE外观模式 -- 结构型模式
查看>>
iOS xcodebuile 自动编译打包ipa
查看>>
程序员眼中的 SQL Server-执行计划教会我如何创建索引?
查看>>
【BZOJ】1624: [Usaco2008 Open] Clear And Present Danger 寻宝之路(floyd)
查看>>
cmake总结
查看>>
数据加密插件
查看>>
linux后台运行程序
查看>>
win7 vs2012/2013 编译boost 1.55
查看>>
IIS7如何显示详细错误信息
查看>>
ViewPager切换动画PageTransformer使用
查看>>
coco2d-x 基于视口的地图设计
查看>>
C++文件读写详解(ofstream,ifstream,fstream)
查看>>
Android打包常见错误之Export aborted because fatal lint errors were found
查看>>
Tar打包、压缩与解压缩到指定目录的方法
查看>>
新手如何学习 jQuery?
查看>>
配置spring上下文
查看>>
Python异步IO --- 轻松管理10k+并发连接
查看>>