for
for循环又是类似于c++的。基本差别是shell的for不允许你指定循环的次数或者范围,而只能指定值的固定列表。
for的结构语法:
for name [in list]
do
statements that can use $name.....
done
list为名称列表,如果被省略,则默认为"$@"。
1、前面曾经试过使用模式匹配和替换列出PATH里的目录,一个一行。现在需要打印出PATH的目录,一个一行,并且要打印每个目录的信息,如权限和修改时间。
最简单的方法是通过修改IFS变量。
IFS=:
for dir in $PATH
do
ls -ld $dir
done
代码将IFS设置为冒号,即在PATH中使用的分隔符。然后使用for循环进行遍历,设置dir为PATH中每个冒号分隔的域。-s选项表示值显示目录的本身,不显示其内容。
代码的升级版如下,可以检测目录是否存在:
IFS=:
for dir in "$@"
do
if [ -z "$dir" ]; then dir=.; fi
if ! [ -e "$dir" ]; then
echo "$dir does not exit"
elif ! [ -d "$dir" ]; then
echo "$dir is not a directory"
else
ls -ld $dir
fi
done
(脚本在/home/knight/my/shell/ShowPath.sh)
2、可是使用ls -R选项打印出给定目录下的所有目录。现编写一个脚本,使不同级别目录下显示前面的空格数不同。用到递归。
脚本代码如下:
recdir ()
{
tab=$tab$singletab
for file in "$@"; do
echo -e $tab$file
thisfile=$thisfile/$file
if [ -d "$thisfile" ]; then
recdir $(command ls $thisfile)
fi
thisfile=${thisfile%/*}
done
tab=${tab%"\t"}
}
singletab="\t"
for tryfile in "$@"; do
echo $tryfile
if [ -d "$tryfile" ]; then
thisfile=$tryfile
recdir $(command ls $tryfile)
fi
done
unset dir singletab tab
下面对这段代码稍微解读一下:
脚本里面定义了一个函数recdir()。如果直接递归脚本命令,会调用到多个新shell。如果定义函数,对函数递归,就只在一个shell中,提高了效率。
首先设置变量singletab为一个空格,然后遍历提供给脚本的每一个参数,打印之。如果是目录,则调用递归过程,也就是recdir函数,使用ls给出文件的列表。
注意,其中的command是shell的内置命令,它屏蔽函数和别名查找,在这里确保ls命令来自于路径PATH下,且不是函数。程序结束后,用unset清除使用过的变量。
recdir函数首先每递归一次,就在tab变量后面加上一个singletab。recdir遍历作为参数给出的文件,打印每个文件名。如果该文件为目录,则在此调用自身。
每次进入目录层次的下一层时,都增加一个TAB字符,函数将thisfile设置为file文件所在的目录。调用完一次recdir之后,将thisfile后面一段删除,将tab后面的一个空格删除,返回到上一级目录。这里不用cd而使用相对路径,是为了在每次循环中对文件名进行处理。
阅读(984) | 评论(0) | 转发(0) |