[bash]for、while/until、循环控制、循环输出定向和管接

来源:互联网 发布:quickfix java 编辑:程序博客网 时间:2024/06/05 07:06

1. for命令列表中的元素使用空格分隔:

#!/bin/bashfor x in 1 2 3 4 5 6 7 8#bash默认用空格来分隔迭代值,注意,即使是数字但仍然是字符串doecho $xdoneecho $x#保留迭代的最后一个值for s in abc bca kk dd sldkfjsdoecho $sdone

2. 处理列表元素中的特殊字符(即解析复杂的迭代值):

#!/bin/bashfor w in I don\'t know if "this'll" work#如果迭代值出现',则使用转义或者""括起来都行doecho $wdonefor p in "Xi'an" "Chang sha" Nevada "New York"#如果迭代值本身还有空格,则使用""将迭代值括起来doecho I wanna go to $pdone#总体来说建议同意使用"",看起来更加直观并且方便调试

3. 从变量中获取列表:
#!/bin/bashs="sdf kkk sdfjskdljf skldfjwoei"s=$s" ppppp"#""实际上就是一个构造字符串字面值的运算符,会将括号中的内容作为字符串替换到当前位置,也是一种宏for x in $sdoecho $xdone

如果直接以字符串变量作为迭代对象,则将以字符串中的空白符作为分隔符!比如:

s=“a b c d”for w in $sdoecho $wdone//outputabcdfor w in $s $sdoecho $wdone//outputabcdabcd


4. 从命令中获取列表:

!这种方式同样也是将命令的结果作为一整个字符串看待,所以和上面的例子一样,这种方式下同样是把空白符作为分隔符:

#!/bin/bashfor x in `cat ./test.txt`doecho $xdone
#./test.txtkkkkaaaaadsfffffdfsxzxvadsfbbbbb<span style="white-space:pre"></span>#以空白符作为迭代值的分隔符,若干连续的多个空白符(' '、\t、\n)都会当做一个空白符skdfjwsdfkwdddd vvvvvsdf'sdfkwef<span style="white-space:pre"></span>#由于不是shell源代码文本可以随意使用'和"而无需转义,这是显而易见的!bskdf"sdkf"
#输出kkkkaaaaadsfffffdfsxzxvadsfbbbbbskdfjwsdfkwddddvvvvvsdf'sdfkwefbskdf"sdkf"

5. 修改列表解析的分隔符(使用的文件仍然是4.中的./test.txt):

#!/bin/bash#Internal Field Separator#内部字段分隔符,用于解析列表的分隔符#默认值是' '、\t、\n#值保存在环境变量$IFS中#用户可以在同一个脚本中任意修改,退出脚本后就恢复成了默认值#修改方式为IFS=$'...'#分隔符可以设置多个,修改时直接连接即可,比如:IFS=$',\n\t:'#这里分隔符有, \n \t和:#在解析/etc/passwd文件时用:作为分隔符就比较好!IFSOLD=$IFS#先保存默认值,以便在用完之后可以恢复IFS=$'\n'#修改成\nfor x in `cat ./test.txt`doecho $xdoneIFS=$IFSOLD#恢复成默认值,在接下里的程序中可以使用for x in `cat ./test.txt`doecho $xdoneecho $IFS
#第一个测例的输出:aaadsfffffdfsxzxvadsfbbbbbskdfjwsdfkwdddd vvvvvsdf'sdfkwefbskdf"sdkf"#第二个测例的输出aaaadsfffffdfsxzxvadsfbbbbbskdfjwsdfkwddddvvvvvsdf'sdfkwefbskdf"sdkf"

6. 使用空白符获取列表:

#!/bin/bashfor file in $HOME/*#使用通配符获取列表doif [ -d "$file" ]#Linux是允许文件名含有空格的,$仅仅是一个宏替换,如果含有空格则test命令会将其作为多个参数而不是一个参数处理而报错,因此必须使用""将其作为一个字符串处理thenecho "directory: $file"elif [ -f "$file" ]thenecho "file     : $file"#echo打印字符串时以多个连续的空白符作为一个空格处理,因此需要用""来打印多个连续的空格!!!fidone


7. 多种方式合并使用来获取列表:

#!/bin/bashfor str in `cat test.txt` $HOME/* lllllqqqqqqq#代码中还是以空格作为分隔符即可doecho $strdone

8. C风格的for——for (( )):

#!/bin/bashfor ((i = 10; i; i--))#空格可以随意加,并且在(())中引用变量时不需要$运算符,完全跟C语言一样doecho $i#一旦出了(())就得使用$引用变量了donefor (( a = 1, b = 10; a <= 5 && b >= 7; a++, b-- ))#可以迭代多个值,和C语言一模一样doecho $a - $becho $[ $a + $b ]done

9. 类似C语言逗号表达式的while多条件测试:

#!/bin/bashv=10while echo $v#多测试命令类似C语言的逗号表达式,每条命令占一行(否则会报错!!)echo $v!!#多条件测试和C语言的逗号表达式一样主要用于产生副作用[ $v -ge 0 ]#只有最后一条命令作为循环的判断条件doecho This is in the loopv=$[ $v - 1 ]done

10. until循环:

#!/bin/bashv=100until [ $v -eq 0 ]#知道条件成立才停止循环doecho $vv=$[ $v - 25 ]donev=100until echo $v#until也支持多条件测试[ $v -eq 0 ]doecho Inside the loop(( v = $v - 25 ))done

11. 循环嵌套:

#!/bin/bashfor (( i = 1; i <= 3; i++ ))doecho Starting loop $i:for (( j = 1; j <= 3; j++ ))doecho Inside loop $jdonedonei=5while [ $i -ge 0 ]doecho Outer loop $i:for (( j = 1; j <= 3; j++ ))doecho "Inner loop: $i * $j = $[ $i * $j ]"#*会被bash理解成通配符,所以需要用""括起来表示一个普通字符donei=$[ $i - 1 ]donei=3until [ $i -eq 0 ]doecho Outer loop $i:j=1while [ $j -lt 5 ]dov=`echo "scale = 4; $i / $j" | bc`echo "Inner loop: $i / $j = $v"j=$[ $j + 1 ]donei=$[ $i - 1 ]done

12. 利用IFS和循环嵌套解析/etc/passwd中的内容:

#!/bin/bashIFS=$'\n'#使用$''的形式在脚本中的当前位置彻底改变IFS的值,但是退出脚本后就恢复成默认值for entry in `cat /etc/passwd`do#环境变量也是有作用域的IFS=:#在代码块中直接赋值只能临时改变IFS的值,出了这个代码块该值就无效并恢复成进入代码块之前的值echo Valuse in $entry are:for val in $entrydoecho "$val"donedone

!注意:当用单引号' '引起字符串时不会将$XXX解析成提取变量的内容而是直接当成普通字符串看待,而双引号" "则会解析字符串中的特殊符号,比如:

echo '$HOME'会直接打印出$HOME这个字符串,而echo "$HOME"则会打印出用户的主目录的绝对路径!


13. break命令:

#!/bin/bashfor v in 1 2 3 4 5 6 7 8 9doif [ $v -eq 5 ]thenbreak#不带参数默认为跳出当前最近的一层循环,默认参数为1,表示当前的最近1层循环fiecho Iteration number: $vdoneecho Complete!v=1while [ $v -lt 10 ]doif [ $v -eq 5 ]thenbreakfiecho Iteration number: $vv=$[ $v + 1 ]doneecho Complete!#跳出内存循环for (( i = 1; i < 4; i++ ))doecho Outer loop: $ifor (( j = 1; j < 100; j++ ))doif [ $j -eq 5 ]thenbreakfiecho Inner loop: $jdonedoneecho Complete!#跳出外层循环for (( i = 1; i < 4; i++ ))doecho Outer loop: $ifor (( j = 1; j < 100; j++ ))doif [ $j -gt 4 ]thenbreak 2#向外跳出两层循环,如果没有参数则默认为1,即当前最近的循环fiecho "Inner loop: $j"donedoneecho Complete!

14. continue命令(和break命令用法一样):

#!/bin/bashfor (( i = 1; i < 15; i++ ))doif [ $i -gt 5 ] && [ $i -lt 10 ]thencontinuefiecho Iteration number: $idoneecho Complete!i=0while echo "while iteration: $i"[ $i -lt 15 ]doif [ $i -gt 5 ] && [ $i -lt 10 ]theni=$[ $i + 1 ]#注意!continuefiecho "Inside iteration number: $i"i=$[ $i + 1 ]donefor (( i = 1; i < 10; i++ ))doecho Iteration $i:for (( j = 1; j < 3; j++ ))doif (( 2 < i && i < 6 ))thencontinue 2fiecho "The result of $i * $j = $[ $i * $j ]"donedone

15. 循环重定向和管接:

#!/bin/bashfor file in $HOME/*doif [ -d "$file" ]thenecho $file is a directoryelseecho $file is filefidone > t1.out#将循环的所有echo输出按顺序重定向到指定文件中for (( i = 1; i < 10; i++ ))doecho $idone > t2.outfor state in sfdf aaaa kjsdkf zzflef klsafjdoecho $statedone | sort#将循环echo管接至sort命令中

0 0
原创粉丝点击