以bash方式递归区分文件和目录

时间:2018-04-10 01:42:15

标签: bash recursion

在这里打击。希望编写一个脚本:

  • 将绝对/相对目标目录作为其唯一输入参数并循环其内容
  • 如果其中一个直接子项是文件,我希望它回显“Found a file called $file!”(其中$file是文件的名称)
  • 否则,如果其中一个直接子节点本身就是一个目录,我希望它回显“Found a directory named $dir”(其中$dir是目录的名称),但是 em>我希望它在该目录中以相同的逻辑递归执行,最后我希望它继续循环遍历目标目录的其余部分

因此给出了以下目标目录结构:

~/testDir/
    1.txt
    2.txt
    childDirA/
        foo.png
    3.txt
    childDirB/
        buzz.gif
        childDirC/
            foo.bar
    4.txt

脚本的输出是:

Found a file called 1.txt!
Found a file called 2.txt!
Found a directory named childDirA
Found a file called foo.png!
Found a file called 3.txt!
Found a directory named childDirB
Found a file called buzz.gif!
Found a directory named childDirC
Found a file called foo.bar!
Found a file called 4.txt!

到目前为止,我能想到的最好的是:

#!/bin/bash
for file in $1;
  do echo "Found a file called $file";
done

但是,如果我指向我的testDir,我得到的唯一输出是:

Found a file called testDir

我出错的任何想法?

3 个答案:

答案 0 :(得分:3)

这是一个可以执行该操作的脚本。

function listDir() {
    for file in "$1"/*;
    do
        if [ -f "$file" ]; then
            echo "Found file $(basename "$file")"
        elif [ -d "$file" ]; then
            echo "Found directory $(basename "$file")"
            listDir "$file"
        fi
    done
}

listDir "$1"

答案 1 :(得分:1)

正如Tripp在评论中提到的那样,find可以做到递归'为你工作;那么你只需要将输出调整为你想要的格式。

假设您只需要担心文件和目录:

#!/usr/bin/bash

while IFS= read -d "" -r tgt
do
        # for printing purposes, strip off directory info; basically simulate
        # `basename` without the overhead of spawning an expensive sub-process

        tgtname=${tgt##*/}

        # determine tgt's type : 'file' or 'directory'

        tgttype='file'
        [ -d "${tgt}" ] && tgttype='directory'

        echo "Found a ${tgttype} named ${tgtname}"

done < <(find "$1" -print0)

注意:

  • 单独运行find $1以查看输入循环的数据格式
  • 如果您正在处理链接,设备等,可以添加其他测试以确定tgttype(可能使用case声明吗?)
  • 考虑find的其他命令行参数/参数来微调输入循环的列表

答案 2 :(得分:0)

查找

#!/bin/sh
find "$1" -mindepth 1 -type f -printf 'Found a file called %f!\n' -o -type d -printf 'Found a directory named %f\n'

说明:

默认情况下,find通过子目录进行递归。

find的参数:

  • -mindepth 1排除基目录
  • -type f ...如果找到普通文件,请执行以下操作
  • -o -type d ...或者,如果找到目录,请执行以下操作
  • -printf ...根据给定的格式字符串打印
  • %f文件的基本名称(dirs是此上下文中的文件)