命令格式:
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
566

被折叠的 条评论
为什么被折叠?



