1 for 命令
for
命令的基本格式:
for var in list
do
commands
done
在 list 参数中, 需要提供迭代中要用到的 一系列值.
每次迭代, 变量 $var
会包含 list 的当前值.
do
和 done
语句之间是每次迭代需要执行的命令(组).
for
命令读取列表中的值:
$ cat temp.sh
#!/bin/bash
for var in hello world; do
echo value: $var
done
$ ./temp.sh
value: hello
value: world
如果单项数据 中包含空格
, 则需把单项数据用双引号 "
括起来:
$ cat temp.sh
#!/bin/bash
for username in "miyan" "rosie cui" "mitre chen" "abby wang"; do
echo user: $username
done
$ ./temp.sh
user: miyan
user: rosie cui
user: mitre chen
user: abby wang
我们可以把 "miyan" "rosie cui" "mitre chen" "abby wang"
赋值给一个变量 list
,
然后从 list
中遍历:
$ cat temp.sh
#!/bin/bash
IFS=$'\n'
# echo -e 可以把 \n 转成换行
list=$(echo -e "miyan\nrosie cui\nmitre chen\nabby wang")
for username in $list; do
echo user: $username
done
$ ./temp.sh
user: miyan
user: rosie cui
user: mitre chen
user: abby wang
注意:
环境变量 IFS
(internal field separator, 内部字段分隔符) 默认会把下列字符当成 字段分隔符:
- 空格
- 制表符
- 换行符
所以, 在上面的示例中, 我们先把 IFS
修改为 换行符
, 这样 for
在分割字符串, 只会把每个换行符
前当成一次迭代, 而不会把带空格
的字符串分割成多个迭代.
1.1 从命令读取值
从 命令 $(command)
中读取值赋予 for
命令:
$ cat namefile
mitre chen
rosie cui
$ cat temp.sh
#!/bin/bash
IFS=$'\n'
for name in $(cat namefile); do
echo name: $name
done
$ ./temp.sh
name: mitre chen
name: rosie cui
1.2 用通配符读取目录
for-in
结构中, 在 in
后面使用统配符.
很简单, 看示例:
$ cat temp.sh
#!/bin/bash
for file in /home/miyan/test/*; do
if [ -d "$file" ]; then
echo "$file is a directory"
elif [ -f "$file" ]; then
echo "$file is a file"
fi
done
$ ./temp.sh
/home/miyan/test/811.log is a file
/home/miyan/test/awk is a directory
/home/miyan/test/namefile is a file
/home/miyan/test/symbolicFile2 is a file
/home/miyan/test/temp.sh is a file
1.3 for-in 遍历数字范围
遍历 全数范围(full number range), 示例:
$ cat temp.sh
#!/bin/bash
for i in {1..5}; do
echo "value: $i"
done
echo "======="
for i in {01..05}; do
echo "value: $i"
done
$ ./temp.sh
value: 1
value: 2
value: 3
value: 4
value: 5
=======
value: 01
value: 02
value: 03
value: 04
value: 05
for-in
遍历数字范围还是挺智能的, 能区分开 {1..5}
和 {01..05}
.
for-in
跳跃遍历数字范围:
$ cat temp.sh
#!/bin/bash
# 遍历1..50, 间隔是10
for i in {1..50..10}; do
echo "value: $i"
done
$ ./temp.sh
value: 1
value: 11
value: 21
value: 31
value: 41
2 C 语言风格 for 命令
bash 中 C 语言风格的 for 循环
的格式:
for (( variable assignment; condition; iteration process ))
还记得双括号(())
在 if-then
中处理数学运算吗?
C 语言风格的 for
对于高级语言程序员来说, 很好理解:
$ cat temp.sh
#!/bin/bash
for (( i = 0; i<5; i++)); do
echo "value: $i"
done
$ ./temp.sh
value: 0
value: 1
value: 2
value: 3
value: 4
3 while 命令
while
命令的格式:
while condition
do
commands
done
while
这里的 条件测试 和 if-then
中的 条件测试 格式一模一样. condition 可以使用任何的普通的 bash shell 命令, 或者使用 test
命令进行条件测试.
示例:
$ cat temp.sh
#!/bin/bash
var=3
# 条件测试, 注意空格
while [ $var -gt 0 ]; do
echo $var
var=$[$var-1]
done
echo "=============="
var=3
# 双括号(()) 处理高级数学表达式
while (( $var > 0)); do
echo $var
var=$[$var-1]
done
$ ./temp.sh
3
2
1
==============
3
2
1
还记得吗?
4 until 命令
只有 条件测试 的 退出状态码 不为 0
, until
才会执行循环中的命令; 退出状态码 为 0
, 循环就结束了.
until
命令格式:
until condition
do
commands
done
until
命令示例:
$ cat temp.sh
#!/bin/bash
var=3
until [ $var -le 0 ]; do
echo $var
var=$[$var-1]
done
$ ./temp.sh
3
2
1
5 控制循环
一旦进入了循环, 必须等到循环结束? 不是这样的, 我们可以通过 break
跳出循环, 也可以通过 continue
跳过单个循环.
5.1 break 命令
直接看示例:
cat temp.sh
#!/bin/bash
for i in {1..10}; do
if [ $i -gt 3 ]; then
break;
fi
echo $i
done
$ ./temp.sh
1
2
3
当遍历到 4
时, 大于 3
, break
跳出循环.
break
完整的写法时 break n
, 其中 n
指定了要跳出的 循环层级, 默认情况下, n=1
表示跳出的是当前循环.
如果想要跳出 外层循环, 必须 令 n=2
:
$ cat temp.sh
#!/bin/bash
for i in {1..10}; do
for (( j=0; j<10; j++ )); do
if [ $j -gt 3 ]; then
break 2;
fi
echo "i=$i, j=$j"
done
done
$ ./temp.sh
i=1, j=0
i=1, j=1
i=1, j=2
i=1, j=3
5.2 continue 命令
continue
和 break
的用法相似, 直接看个示例:
$ cat temp.sh
#!/bin/bash
for i in {1..5}; do
if [ $i -eq 3 ]; then
continue
fi
echo "$i"
done
$ ./temp.sh
1
2
4
5
和 break
一样, continue
的完整写法时 continue n
, 其中 n
指定了要跳过的 循环层级, 默认情况下, n=1
表示跳过的是当前循环一次迭代.
6 处理循环的输出
在 shell 脚本种, 可以对循环的输出 使用 管道 或 重定向, 通过在 done
命令后面添加一个处理命令实现.
在 for
命令中使用 输出重定向 把 循环的输出 重定向 到文件中:
$ cat temp.sh
#!/bin/bash
for i in {1..5}; do
if (( $i % 2 == 0)); then
echo "$i even"
else
echo "$i odd"
fi
done > temp.log
$ ./temp.sh
$ cat temp.log
1 odd
2 even
3 odd
4 even
5 odd
在 for
命令中使用 管道, 把 循环的输出 通过 管道 传给另一个命令:
$ cat temp.sh
#!/bin/bash
for i in {1..5}; do
if (( $i % 2 == 0)); then
echo "$i even"
else
echo "$i odd"
fi
done | sort -r
$ ./temp.sh
5 odd
4 even
3 odd
2 even
1 odd
Reference
[1]. Linux命令行与shell脚本编程大全(第三版)