命令格式:
for var in list; do
commands
done
- 读取列表中的值
$ cat test1
#!/bin/bash
# basic for command
for test in Alabama California Colorado; do
echo The next state is $test
done
$ ./test1
The next state is Alabama
The next state is California
The next state is Colorado
1.1 讀取數組中的值
--------------------------------------------------
for 循環讀取方法
for i in ${variable[@]}; do
# do something....
done
--------------------------------------------------
[oracle@DB02 myshell]$ cat test_array.sh
#!/bin/bash
# basic for command
#
arr=("aa" "bb" "cc")
echo "所有的内容如下:" ${arr[@]}
#数组的下标从0开始
echo "第 2 個 元素值:" ${arr[1]}
echo "数组的长度方法1:" ${#arr[*]}
echo "数组的长度方法2:" ${#arr[@]}
for var in ${arr[@]}; do
echo "打印的内容:" $var
done
[oracle@DB02 myshell]$ ./test_array.sh
所有的内容如下: aa bb cc
第 2 個 元素值: bb
数组的长度方法1: 3
数组的长度方法2: 3
打印的内容: aa
打印的内容: bb
打印的内容: cc
1.2 讀取字典中的值
[oracle@DB02 15]$ cat test_dict.sh
#!/bin/bash
#
echo "shell定义字典"
#必须先声明
declare -A dic
#dic=([key1]="value1" [key2]="value2" [key3]="value3")
dic["key1"]="values1"
dic["key3"]="values3"
dic["key5"]="values5"
#打印指定key的value
echo ${dic["key1"]}
#打印所有key值
echo ${!dic[*]}
#打印所有value
echo ${dic[*]}
#遍历key值
for key in $(echo ${!dic[*]}); do
echo "$key : ${dic[$key]}"
done
---------------------------------------------------------------
[oracle@DB02 15]$ ./test_dict.sh
shell定义字典
values1
key5 key3 key1
values5 values3 values1
key5 : values5
key3 : values3
key1 : values1
- 读取列表中的复杂值(列表值中含单引号)
有两种办法可解决这个问题:
使用转义字符(反斜线)来将单引号转义;
使用双引号来定义用到单引号的值
$ cat test2
#!/bin/bash
# another example of how not to use the for command
for test in I don\'t know if "this'll" work; do
echo "word : $test"
done
$ ./test2
word : I
word : don't
word : know
word : if
word : this'll
word : work
#在第一个有问题的地方添加了反斜线字符来转义don't中的单引号。在第二个有问题的地方将this'll用双引号圈起来。两种方法都能正常辨别出这个值
#for命令用空格来划分列表中的每个值。如果在单独的数据值中有空格,就必须用双引号将这些值圈起来
$ cat test3
#!/bin/bash
# an example of how to properly define values
for test in Nevada "New Hampshire" "New Mexico" "New York"; do
echo "Now going to $test"
done
$ ./test3
Now going to Nevada
Now going to New Hampshire
Now going to New Mexico
Now going to New York
- 从变量读取列表
$ cat test4
#!/bin/bash
# using a variable to hold the list
list="Alabama Colorado"
list=$list" Connecticut"
for state in $list; do
echo "Have you ever visited $state?"
done
$ ./test4
Have you ever visited Alabama?
Have you ever visited Colorado?
Have you ever visited Connecticut?
- 从命令读取值 & 更改字段分隔符
默认情况下,bash shell会将下列字符当作字段分隔符:
空格
制表符
换行符
在处理可能含有空格的数据时可以在shell脚本中临时更改IFS环境变量的值来限制被bash shell当作字段分隔符的字符。
例如,如果你想修改IFS的值,使其只能识别换行符(告诉bash shell在数据值中忽略空格和制表符),那就必须这么做:
IFS=$'\n'
案例1
$ cat test5b
#!/bin/bash
# reading values from a file
file="states"
IFS=$'\n'
for state in $(cat $file); do
echo "Visit beautiful $state"
done
$ cat states
Alabama
Colorado
Delaware
New York
North Carolina
$ ./test5b
266 第 13 章 更多的结构化命令
Visit beautiful Alabama
Visit beautiful Colorado
Visit beautiful Delaware
Visit beautiful New York
Visit beautiful North Carolina
你要做的就是将IFS的值设为冒号。
IFS=:
如果要指定多个IFS字符,只要将它们在赋值行串起来就行。
IFS=$'\n':;"
这个赋值会将换行符、冒号、分号和双引号作为字段分隔符
- 用通配符读取目录
应该将$file变量用双引号圈起来。如果不这么做,遇到含有空格的目录名或文件名时就会有错误产生
$ cat test6
#!/bin/bash
# iterate through all the files in a directory
for file in /home/rich/test/*; do
if [ -d "$file" ]; then
echo "$file is a directory"
elif [ -f "$file" ]; then
echo "$file is a file"
fi
done
$ ./test6
/home/rich/test/dir1 is a directory
/home/rich/test/myprog.c is a file
/home/rich/test/testprog.c is a file
6.bash中C语言风格的for循环
基本格式:
for (( variable assignment ; condition ; iteration process ))
do
...
done
or
for (( variable assignment ; condition ; iteration process )); do
...
done
案例
$ cat test8
#!/bin/bash
# testing the C-style for loop
for (( i=1; i <= 5; i++ ))
do
echo "The next number is $i"
done
$ ./test8
The next number is 1
The next number is 2
The next number is 3
The next number is 4
The next number is 5
使用多个变量:
可以为每个变量定义不同的迭代过程。尽管可以使用多个变量,但你只能在for循环中定义一种条件
$ cat test9
270 第 13 章 更多的结构化命令
#!/bin/bash
# multiple variables
for (( a=1, b=10; a <= 10; a++, b-- )); do
echo "$a - $b"
done
$ ./test9
1 - 10
2 - 9
...
9 - 2
10 - 1
- while 命令
while命令的格式是:
while test command
do
other commands
done
$ cat test10
#!/bin/bash
# while command test
var1=10
while [ $var1 -gt 0 ]
do
echo $var1
var1=$[ $var1 - 1 ]
done
$ ./test10
10
9
...
2
1
- until 命令
until命令的格式如下。
until test commands
do
other commands
done
案例:
$ cat test12
#!/bin/bash
# using the until command
var1=100
until [ $var1 -eq 0 ]
do
echo $var1
var1=$[ $var1 - 25 ]
done
$ ./test12
100
75
50
25
- 案例-循环处理文件数据
典型的例子是处理/etc/passwd文件中的数据。这要求你逐行遍历/etc/passwd文件,
并将IFS变量的值改成冒号,这样就能分隔开每行中的各个数据段了
#!/bin/bash
# changing the IFS value
IFS.OLD=$IFS
IFS=$'\n'
for entry in $(cat /etc/passwd)
do
echo "Values in $entry –"
IFS=:
for value in $entry
do
echo " $value"
done
done
在运行这个脚本时,你会得到如下输出。
Values in rich:x:501:501:Rich Blum:/home/rich:/bin/bash -
rich
501
501
Rich Blum
/home/rich
/bin/bash
Values in katie:x:502:502:Katie Blum:/home/katie:/bin/bash -
katie
x
506
509
Katie Blum
/home/katie
/bin/bash
- break 命令 (用break命令来退出任意类型的循环,包括while和until循环)
10.1 跳出单个循环
$ cat test17
#!/bin/bash
# breaking out of a for loop
for var1 in 1 2 3 4 5 6 7 8 9 10
do
if [ $var1 -eq 5 ]
then
break
fi
echo "Iteration number: $var1"
done
echo "The for loop is completed"
./test17
Iteration number: 1
Iteration number: 2
Iteration number: 3
Iteration number: 4
The for loop is completed
$ cat test18
#!/bin/bash
# breaking out of a while loop
var1=1
while [ $var1 -lt 10 ]
do
if [ $var1 -eq 5 ]
then
break
fi
echo "Iteration: $var1"
var1=$[ $var1 + 1 ]
done
echo "The while loop is completed"
$ ./test18
Iteration: 1
Iteration: 2
Iteration: 3
Iteration: 4
The while loop is completed
10.2 跳出内部循环
$ cat test19
#!/bin/bash
# breaking out of an inner loop
for (( a = 1; a < 3; a++ )); do
echo "Outer loop: $a"
for (( b = 1; b < 100; b++ )); do
if [ $b -eq 5 ]
then
break
fi
echo " Inner loop: $b"
done
done
$ ./test19
Outer loop: 1
Inner loop: 1
Inner loop: 2
Inner loop: 3
Inner loop: 4
Outer loop: 2
Inner loop: 1
Inner loop: 2
Inner loop: 3
Inner loop: 4
10.3 跳出外部循环
有时你在内部循环,但需要停止外部循环。break命令接受单个命令行参数值:
break n
其中n指定了要跳出的循环层级。默认情况下,n为1,表明跳出的是当前的循环。如果你将n设为2,
break命令就会停止下一级的外部循环
$ cat test20
#!/bin/bash
# breaking out of an outer loop
for (( a = 1; a < 4; a++ )); do
echo "Outer loop: $a"
for (( b = 1; b < 100; b++ )); do
if [ $b -gt 3 ]
then
break 2
fi
echo " Inner loop: $b"
done
done
$ ./test20
Outer loop: 1
Inner loop: 1
Inner loop: 2
Inner loop: 3
- continue 命令
$ cat test21
#!/bin/bash
# using the continue command
for (( var1 = 1; var1 < 15; var1++ ))
do
if [ $var1 -gt 5 ] && [ $var1 -lt 10 ]
then
continue
fi
echo "Iteration number: $var1"
done
$ ./test21
Iteration number: 1
Iteration number: 2
Iteration number: 3
Iteration number: 4
Iteration number: 5
Iteration number: 10
Iteration number: 11
Iteration number: 12
Iteration number: 13
Iteration number: 14
和break命令一样,continue命令也允许通过命令行参数指定要继续执行哪一级循环:
continue n
其中n定义了要继续的循环层级。下面是继续外部for循环的一个例子:
$ cat test22
#!/bin/bash
# continuing an outer loop
for (( a = 1; a <= 5; a++ )); do
echo "Iteration $a:"
for (( b = 1; b < 3; b++ )); do
if [ $a -gt 2 ] && [ $a -lt 4 ]
then
continue 2
fi
var3=$[ $a * $b ]
echo " The result of $a * $b is $var3"
done
done
$ ./test22
Iteration 1:
The result of 1 * 1 is 1
The result of 1 * 2 is 2
Iteration 2:
The result of 2 * 1 is 2
The result of 2 * 2 is 4
Iteration 3:
Iteration 4:
The result of 4 * 1 is 4
The result of 4 * 2 is 8
Iteration 5:
The result of 5 * 1 is 5
The result of 5 * 2 is 10
- 对循环的输出使用管道或进行重定向
$ cat test23
#!/bin/bash
# redirecting the for output to a file
for (( a = 1; a < 6; a++ )); do
echo "The number is $a"
done > test23.txt
echo "The command is finished."
$ ./test23
The command is finished.
$ cat test23.txt
The number is 1
The number is 2
The number is 3
The number is 4
The number is 5
$ cat test24
#!/bin/bash
# piping a loop to another command
for state in "North Dakota" Connecticut Alabama; do
echo "$state is the next place to go"
done | sort
echo "This completes our travels"
$ ./test24
Alabama is the next place to go
Connecticut is the next place to go
North Dakota is the next place to go
This completes our travels
网友评论