linux sh脚本 while,Linux 命令 & shell 脚本之06(for、while、until 命令)

命令格式:

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值