欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Linux Shell系列教程:Shell for循环语法

程序员文章站 2022-07-08 18:22:39
13.1、Shell for循环语法 for 变量 in 列表 do command1 command2 ... commandN done...

13.1、Shell for循环语法

for 变量 in 列表
do
    command1
    command2
    ...
    commandN
done

**也可以写成:for var in list; do

13.1.1、读取列表中的值
#!/bin/bash
#basic for command

for test in Alabama BOb Tom Console
do
  echo The next state is $test
done

执行结果:

The next state is Alabama
The next state is BOb
The next state is Tom
The next state is Console

在最后一次迭代后,$test变量的值会在shell脚本的剩余部分保持有效。它会一直保持最后一次迭代的值(除非你修改了它)。

13.1.2、读取列表中的复杂值
有两种解决办法:
*使用转义字符(反斜线)来将单引号转移;
*使用双引号来定义用到单引号的值。
#!/bin/bash
#basic for command

for test in I don\'t think if "this'll" work
do
  echo The next state is $test
done

执行结果:

The next state is I
The next state is don't
The next state is think
The next state is if
The next state is this'll
The next state is work

*记住,for命令用空格来划分列表中的每个值。如果在单独的数据值中有空格,就必须用双引号将这些值圈起来。

13.1.3、从变量读取列表
将一系列的值都集中存储在一个变量中,然后需要遍历变量中的整个列表。
#!/bin/bash
#using a variable to hold the list

list="Alabama BOb Tom Console"
#向已有列表中添加或拼接一个值
list=$list" success"
for state in $list
do
  echo "this word  is $state"
done

执行结果:

this word  is Alabama
this word  is BOb
this word  is Tom
this word  is Console
this word  is success

13.1.4、从命令读取值

生成列表中所需值就是使用命令的输出。

#!/bin/bash
# reading values from a file

file="states"
#for state in `ps -ef | grep  'tomcat.8701' | awk '{print $2}'`
for state in $(cat $file)
do
   echo "visit beautiful $state"
done

states文件内容;

Alabama BOb
Tom Console

执行结果:

visit beautiful Alabama
visit beautiful BOb
visit beautiful Tom
visit beautiful Console
13.1.5、更改字段分隔符
造成这个问题的原因是特殊的环境变量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 "visit beautiful $state"
done

执行结果:

visit beautiful Alabama BOb
visit beautiful Tom Console

一个可参考的安全实践是在改变IFS之前保存原来的IFS值,之后再恢复它。
实现:

IFS.OLD=$IFS
IFS=$'\n'
<在代码中使用新的IFS值>
IFS=$IFS.OLD

这就保证了在脚本的后续操作中使用的是IFS的默认值。
遍历一个文件中用冒号分隔的值:

IFS=:

如果要指定多个IFS字符,只要将它们在赋值行串起来就行。

IFS=$'\n':;"

这个赋值会将换行符、冒号、分号和双引号作为字段分隔符。如何使用IFS字符解析数据没有任何限制。

13.1.6、用通配符读取目录

for file in /proc/*;  
do  
echo $file is file path \! ;  
done 
13.2、类C风格for循环的语法格式
for((expr1; expr2; expr3))  
do  
    command  
    command  
    ...  
done 

有些部分并没有遵循bash shell标准的for命令:
*变量赋值可以有空格
*条件中的变量不以美元符开头
*迭代过程的算式为用expr命令格式

ex9、输出前5个正数

#!/bin/bash
#使用类C风格for循环输出1~5  
for ((integer = 1; integer <= 5; integer++))   
do  
    echo "$integer"  
done  

[zhangqi@localhost shellscript]$ sh for_ex9.sh   
1  
2  
3  
4  
5  

尽管可以使用多个变量,但你只能在for循环中定义一种条件。

#!/bin/bash
for ((a=1,b=10;a<=10;a++,b--))
do
   echo "$a - $b"
done

执行结果:

1 - 10
2 - 9
3 - 8
4 - 7
5 - 6
6 - 5
7 - 4
8 - 3
9 - 2
10 - 1

使用类C风格for循环要注意以下事项:
a.如果循环条件最初的退出状态为非0,则不会执行循环体
b.当执行更新语句时,如果循环条件的退出状态永远为0,则for循环将永远执行下去,从而产生死循环
c.Linux shell中不运行使用非整数类型的数作为循环变量
d.如果循环体中的循环条件被忽略,则默认的退出状态为0
e.在类C风格的for循环中,可以将三个语句全部忽略掉,下面是合法的for循环

for((; ; ))  
do  
    echo "hello world"  
done