bash shell提供了for命令,允许你创建一个遍历一系列值的循环,每个迭代都通过一个该系列中的值执行一组预定义的命令。其格式为
forvar in list
do
commands
done
for命令行中的变量名前面不加前缀”$”。commands中,使用该变量时要加前缀,$var变量包含着每次迭代对应的当前那个列表中的值,列表可以是字符串也可以是序列。
for循环使用的场景
读取列表中的值
这是最基本的用法,即遍历for命令自身中定义的一系列值,如
forvar in value_1 value_2 value_3 value_4 … value_n
do
commands
done
其中,value_1等可以保存在一个变量中。如
$list="xx1 xx2"
$ forvar in $list;do echo $var;done
xx1
xx2
在最后一次迭代后,$var变量的值会在脚本中的剩余部分一直有效,除非对其做了修改。
还可以将for命令行中的列表值写成{n1..n2}形式,这样使得代码简洁,如
#创建多个空白文件
forvar in {1..100}.txt
do
touch $var
done
在上面的代码中,{1..100} 会扩展成一个字符串“1, 2, 3, 4, 5, 6, 7 ,…100”。
可以借助echo很容易生成序列,如echo {1..50} 能够生成一个从1~50 的数字列表。echo {a..z}或{A..Z}或{a..h}可以生成字母列表。
从命令替换中读取值
即for命令行中列表的值取自某个命令的输出,可以使用反引号来执行任何能产生输出的命令。如
for var in `cat $file`
do
commands
done
这里要注意,for 命令以每次一行的方式遍历file文件,bash shell会将空格、制表符和换行符作为字段分隔符(这称为IFS(Internal Field Separator),内部字段分隔符,是存储分隔符的环境变量,shell 环境使用的默认定界字符串),它在看到这些字符后,会认为开始了一个新的数据段,从而加入到for列表中。这样造成文本中某一行如果出现空格的情况下,for命令将每个单词当做单独的值。要避免这一点可以临时修改以下IFS环境变量,如只将换行符作为字符分隔符:IFS=$’\n’。
在一个脚本中改变IFS,通常格式为
oldIFS=$IFS;
IFS=":" #以:作为字符分隔符
#其他脚本语句
IFS=$oldIFS #恢复
用通配符读取目录
使用for命令自动遍历满是文件的目录,但必须在文件名中使用通配符。
I'm trying to write a short script that changes the file names in the folders containing music (mp3)
files. The current format is often along the lines of:"Artist Name - Album
Name - tracknum - Trackname.mp3"and I'd like to shorten this to just:
"tracknum Trackname.mp3"。
[root@NGFW xx]# ll
total1684
-rw-r--r--1 root root 958625 2018-02-01 14:39 123
-rw-r--r--1 root root 759677 2018-02-01 14:39 ????? - D67.mp3
[root@NGFW xx]#
[root@NGFW xx]# for I in *.mp3;do aa=${I##*-}; bb=`echo $aa | sed 's/ //g'`; mv"$I" $bb;done
[root@NGFW xx]# ll
total1684
-rw-r--r--1 root root 958625 2018-02-01 14:39 123
-rw-r--r--1 root root 759677 2018-02-01 14:39 D77.mp3
[root@NGFW xx]#
C语言风格的for循环
for((i=0;i<10;i++))
{
commands; #使用变量$i
}
网友评论