Linux shell 学习笔记(9)— 循环语句(for、while)以及更改字段分隔符

1. for 语句

bash shell 中 for 命令的基本格式如以下,$var 变量包含着这次迭代对应的当前列表项中的值。

for var in list
do
	commands
done

也可以将 do 语句和 for 语句放在同一行,但必须用分号将其同列表中的值分开:for var in list; do

1.1 读取列表中的值

for 命令最基本的用法就是遍历 for 命令自身所定义的一系列值。

$ cat test1
#!/bin/bash
# basic for command
for test in Alabama Alaska Arizona Arkansas California Colorado
do
	echo The next state is $test
done
$ ./test1
The next state is Alabama
The next state is Alaska
The next state is Arizona
The next state is Arkansas
The next state is California
The next state is Colorado
$

1.2 读取列中的复杂值

当列表中包含单引号时,需要使用转义字符或者双引号来定义用到单引号的值。

$ 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
$

记住,for循环假定每个值都是用空格分割的。

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
$

1.3 从变量读取列表

将一系列值都集中存储在了一个变量中,然后需要遍历变量中的整个列表。

$ cat test4
#!/bin/bash
# using a variable to hold the list
list="Alabama Alaska Arizona Arkansas Colorado"
list=$list" Connecticut"	# 向 list 变量中添加文本
for state in $list
do
	echo "Have you ever visited $state?"
done
$ ./test4
Have you ever visited Alabama?
Have you ever visited Alaska?
Have you ever visited Arizona?
Have you ever visited Arkansas?
Have you ever visited Colorado?
Have you ever visited Connecticut?
$

注意,代码还是用了另一个赋值语句向 $list 变量包含的已有列表中添加(或者说是拼接)了一个值。这是向变量中存储的已有文本字符串尾部添加文本的一个常用方法。

1.4 从命令读取值

可以用命令替换来执行任何能产生输出的命令,然后在 for 命令中使用该命令的输出。

$ cat test5
#!/bin/bash
# reading values from a file
file="states"
for state in $(cat $file)
do
	echo "Visit beautiful $state"
done
$ cat states
Alabama
Alaska
Arizona
Arkansas
Colorado
Connecticut
Delaware
Florida
Georgia
$ ./test5
Visit beautiful Alabama
Visit beautiful Alaska
Visit beautiful Arizona
Visit beautiful Arkansas
Visit beautiful Colorado
Visit beautiful Connecticut
Visit beautiful Delaware
Visit beautiful Florida
Visit beautiful Georgia
$

1.5 使用通配符读取目录

可以用 for 命令来自动遍历目录中的文件。进行此操作时,必须在文件名或路径名中使用通配符。它会强制 shell 使用文件扩展匹配。文件扩展匹配是生成匹配指定通配符的文件名或路径名的过程。

如果不知道所有的文件名,这个特性在处理目录中的文件时就非常好用。

$ 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/myprog is a file
/home/rich/test/myscript is a file
/home/rich/test/newdir is a directory
/home/rich/test/newfile is a file
/home/rich/test/newfile2 is a file
/home/rich/test/testdir is a directory
/home/rich/test/testing is a file
/home/rich/test/testprog is a file
/home/rich/test/testprog.c is a file
$

2. C 语言风格的 for 命令

待补充

3. while 命令

3.1 while 的基本格式

while test command
do
	other commands
done

while 命令的关键在于所指定的 test command 的退出状态码必须随着循环中运行的命令而
改变。如果退出状态码不发生变化, while 循环就将一直不停地进行下去。

最常见的 test command 的用法是用方括号来检查循环命令中用到的 shell 变量的值。

$ cat test10
#!/bin/bash
# while command test
var1=10
while [ $var1 -gt 0 ]
do
    echo $var1
    var1=$[ $var1 - 1 ]
done
$ ./test10
10
9
8
7
6
5
4
3
2
1
$

3.2 until 命令

until 命令和 while 命令工作的方式完全相反。until 命令要求你指定一个通常返回非零退出状态码的测试命令。只有测试命令的退出状态码不为 0,bash shell 才会执行循环中列出的命令。一旦测试命令返回了退出状态码 0,循环就结束了。

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
$

4. 控制循环

4.1 break 命令

break 命令是退出循环的一个简单方法。可以用 break 命令来退出任意类型的循环,包括 while 和until 循环。

$ 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
$

4.2 continue 命令

continue 命令可以提前中止某次循环中的命令,但并不会完全终止整个循环。

5. 处理循环的输出

可以对循环的输出使用管道或进行重定向。这可以通过在 done 命令之后添加一个处理命令来实现。

for file in /home/rich/*
do
    if [ -d "$file" ]
    then
    	echo "$file is a directory"
    elif
    	echo "$file is a file"
    fi
done > output.txt

shell 会将 for 命令的结果重定向到文件 output.txt 中,而不是显示在屏幕上。

6. 更改字段分隔符

内部字段分隔符(internal field separator),IFS 环境变量定义了 bash shell 用作字段分隔符的一系列字符。

默认情况下,bash shell 会将下列字符当作字段分隔符:

  • 空格
  • 制表符
  • 换行符

在处理代码量较大的脚本时,可能在一个地方需要修改 IFS 的值,然后忽略这次修改,在脚本的其他地方继续沿用 IFS 的默认值。一个可参考的安全实践是在改变 IFS 之前保存原来的 IFS 值,之后再恢复它。

这种技术可以这样实现:

IFS.OLD=$IFS
IFS=$'\n'

<在代码中使用新的IFS值>

IFS=$IFS.OLD

这就保证了在脚本的后续操作中使用的是 IFS 的默认值。如果要指定多个IFS字符,只要将它们在赋值行串起来就行。

IFS=$'\n':;"

这个赋值会将换行符、冒号、分号和双引号作为字段分隔符。

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值