循环不管在程序中还是脚本中都需要经常用到,在写shell脚本时,经常需要for进行100次循环。for 循环是固定循环,也就是在循环时已经知道需要进行几次循环。有时也把 for 循环称为计数循环。 Shell for循环语法 for 变量 in 列表 do command1 command2 ... commandN done **也可以写成:for var in list; do 读取列表中的值 #!/bin/bash #basic for command for linuxidc in Linux公社 Linuxmi linux Ubuntu do echo The next state is $linuxidc done 执行结果: linuxidc@linuxidc:~/linuxidc.com$ ./linuxidc.sh The next state is Linux公社 The next state is Linuxmi The next state is linux The next state is Ubuntu 在最后一次迭代后,$linuxidc变量的值会在shell脚本的剩余部分保持有效。它会一直保持最后一次迭代的值(除非你已经修改了它)。 读取列表中的复杂值 有两种解决办法: *使用转义字符(反斜线)来将单引号转移; *使用双引号来定义用到单引号的值。 #!/bin/bash #basic for command for linuxidc in Kotlin Linuxmi\'com linux Ubuntu "CentOS'rhel" Oracle do echo The next state is $linuxidc done 执行结果: linuxidc@linuxidc:~/linuxidc.com$ ./linuxidc.sh The next state is Kotlin The next state is Linuxmi'com The next state is linux The next state is Ubuntu The next state is CentOS'rhel The next state is Oracle *记住,for命令用空格来划分列表中的每个值。如果在单独的数据值中有空格,就必须用双引号将这些值圈起来。 从变量读取列表 将一系列的值都集中存储在一个变量中,然后需要遍历变量中的整个列表。 #!/bin/bash #using a variable to hold the list list="Linuxidc Linuxmi Ubuntu Fedora" #向已有列表中添加或拼接一个值 list=$list" success" for state in$list do echo"this word is $state" done 执行结果: linuxidc@linuxidc:~/linuxidc.com$ ./linuxidc.sh this word is Linuxidc this word is Linuxmi this word is Ubuntu this word is Fedora this word is success 从命令读取值 有两种方式可以将命令输出赋值给变量: (1)反引号字符(`) (2)$()格式 例如: linuxidc=`date` linuxidc=$(date) 生成列表中所需值就是使用命令的输出。 #!/bin/bash # reading values from a file file="states" for state in $(cat $file) do echo"welcome $state" done states文件内容; www.linuxidc.com Hello World Linuxmi com linuxidc.net Linux公社 执行结果: linuxidc@linuxidc:~/linuxidc.com$ ./linuxidc.sh welcome www.linuxidc.com welcome Hello welcome World welcome Linuxmi 更改字段分隔符 造成这个问题的原因是特殊的环境变量IFS,叫作内部字段分隔符。默认情况下,bash shell会将下列字符当作字段分隔符: *空格 *制表符 *换行符 如果bash shell在数据中看到这些字符中的任意一个,它就会假定这表明了列表中一个新数据字段的开始。 想修改IFS的值,使其只能识别换行符,那就必须: IFS=$'\n' 将这个语句加入到脚本中,告诉bash shell在数据值中忽略空格和制表符。 #!/bin/bash # reading values from a file file="states" IFS=$'\n' for state in $(cat $file) do echo"Welcome $state" done 执行结果: Welcome www.linuxidc.com Welcome Hello World Welcome Linuxmi com Welcome linuxidc.net Linux公社 一个可参考的安全实践是在改变IFS之前保存原来的IFS值,之后再恢复它。 实现: IFS.OLD=$IFS IFS=$'\n' <在代码中使用新的IFS值> IFS=$IFS.OLD 这就保证了在脚本的后续操作中使用的是IFS的默认值。 遍历一个文件中用冒号分隔的值: IFS=: 如果要指定多个IFS字符,只要将它们在赋值行串起来就行。 IFS=$'\n':;" 这个赋值会将换行符、冒号、分号和双引号作为字段分隔符。如何使用IFS字符解析数据没有任何限制。 用通配符读取目录 #!/bin/bash for file in /home/linuxidc/linuxidc.com/*; do echo$file is file path \! ; done 执行结果: linuxidc@linuxidc:~/linuxidc.com$ ./linuxidc.sh /home/linuxidc/linuxidc.com/03.jpg is file path ! /home/linuxidc/linuxidc.com/123.jpg is file path ! /home/linuxidc/linuxidc.com/123.png is file path ! /home/linuxidc/linuxidc.com/2.avi is file path ! /home/linuxidc/linuxidc.com/amp is file path ! /home/linuxidc/linuxidc.com/atom-amd64.deb is file path ! /home/linuxidc/linuxidc.com/car.jpg is file path ! /home/linuxidc/linuxidc.com/car.png is file path ! /home/linuxidc/linuxidc.com/chenduling.jpg is file path ! /home/linuxidc/linuxidc.com/com.testdemo.java is file path ! /home/linuxidc/linuxidc.com/DarkPicDir is file path ! /home/linuxidc/linuxidc.com/data is file path ! 类C风格for循环的语法格式 for((expr1; expr2; expr3)) do command command ... done 有些部分并没有遵循bash shell标准的for命令: *变量赋值可以有空格 *条件中的变量不以美元符开头 *迭代过程的算式为用expr命令格式 ex9、输出前6个正数 #!/bin/bash #使用类C风格for循环输出1~6 for ((integer = 1; integer <= 6; integer++)) do echo"$integer" done 执行如下: 尽管可以使用多个变量,但你只能在for循环中定义一种条件。 #!/bin/bash for ((x=1,y=8;x<=8;x++,y--)) do echo"$x - $y" done 执行如下: Linux公社的RSS地址:https://www.linuxidc.com/rssFeed.aspx 本文永久更新链接地址:https://www.linuxidc.com/Linux/2019-05/158700.htm 支持就点下在看并转发朋友圈吧 ---------------------------------------------------------------------------------------------------------------------- 我们尊重原创,也注重分享,文章来源于微信公众号:Linux公社,建议关注公众号查看原文。如若侵权请联系qter@qter.org。 ---------------------------------------------------------------------------------------------------------------------- |