Chinaunix首页 | 论坛 | 博客
  • 博客访问: 325410
  • 博文数量: 82
  • 博客积分: 1530
  • 博客等级: 上尉
  • 技术积分: 771
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-16 03:44
文章分类

全部博文(82)

文章存档

2011年(6)

2010年(76)

我的朋友

分类: LINUX

2010-05-02 03:39:02

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而使用相对路径,是为了在每次循环中对文件名进行处理。


阅读(974) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~