如何在Bash中递归列出子目录,而不使用"find"或"ls"命令?

14 浏览
0 Comments

如何在Bash中递归列出子目录,而不使用"find"或"ls"命令?

我知道你可以使用find命令来完成这个简单的任务,但是我有一个任务要求不能使用findls命令来完成,而要怎么做呢?

0
0 Comments

如何在Bash中递归列出子目录而不使用"find"或"ls"命令?

在上面的内容中,我们可以看到一个可能的实现。这是一个名为"my_ls"的函数,它可以递归地列出给定目录的内容和子目录。该函数的参数有两个,第一个参数是要列出内容的目录,第二个参数是缩进。

该函数的实现过程如下:

- 首先,保存当前目录并切换到传入的目录。

- 然后,对于每个非隐藏的文件或目录,打印文件或目录的名称。

- 如果是目录,则进入该目录并继续递归列出其内容。

- 最后,恢复之前保存的目录。

通过调用"my_ls .",我们可以递归列出当前目录及其子目录中的文件。

如果要修改上述脚本以打印文件的完整路径而不只是缩进的文件/目录名称,可以考虑去掉"pushd"和"popd"命令,并且不再需要第二个参数"$2"。

另外,注意到代码中使用了"test XYZ && command"的形式,它与"if test XYZ ; then command ; fi"完全等价。"test XYZ"也等价于"[ XYZ ]",因此上述代码还等价于"if [ XYZ ] ; then command ; fi"。

如果移除"test -e "$file" &&"条件(只保留"echo"),可以看到发生了什么。

如果移除对"$file"的双引号,并且目录中的文件名包含空格,可以看到发生了什么。可以在脚本的顶部添加"set -x"来打开调试输出,并详细查看发生了什么(可以将调试输出重定向到文件,运行"sh -x scriptname.sh 2>debugoutput.txt")。

为了列出隐藏文件(如".bashrc"),可以在"for"循环中添加".?*"的模式,然后在判断中排除".."。

还可以使用子shell来代替"pushd"/"popd"的使用。

需要注意的是,在某些shell实现中,对于"for"(或任何内置命令或外部命令)的参数有一个硬限制(大约4k个字符)。由于shell会在实际执行"for"之前将"*"扩展为匹配的文件名列表,所以如果在具有大量文件的目录中扩展"*",可能会遇到问题(与在相同目录中运行"ls *"时遇到的问题相同,比如出现"Command too long"的错误)。

如果要列出隐藏文件,可以使用"shopt -s dotglob"命令。但这个命令不是可移植的。使用".*"(或".?*"以跳过".")即可达到相同的效果,并且是可移植的。

0
0 Comments

问题的原因是有人想要在Bash中递归列出子目录,但不想使用"find"或"ls"命令。有人建议使用tree -d命令来实现,但却被给出-1的评分。有人解释说这是因为问题要求写出算法,而不是找到一个和ls功能相同但不叫ls的命令。另外,可能有人的需求是在Solaris、AIX或HPUX等非Linux系统上运行,而这些系统默认没有tree命令。

0
0 Comments

问题的出现原因:该问题是因为需要在Bash中递归列出子目录,但是不能使用"find"或"ls"命令。

解决方法1:

#!/bin/bash
recurse() {
 for i in "$1"/*;do
    if [ -d "$i" ];then
        echo "dir: $i"
        recurse "$i"
    elif [ -f "$i" ]; then
        echo "file: $i"
    fi
 done
}
recurse /path

解决方法2:

#!/bin/bash
shopt -s globstar
for file in /path/**
do
    echo $file
done

这些方法也是有效的答案,并且可以避免使用"find"或"ls"命令。

然而,第一种方法在目录为空的情况下会失败,会打印出"dir: bla/*",因为"bla/*"被视为字面量,没有子目录。可以通过使用"pushd/popd"命令,或在"do"之后的第一行添加"if [[ "$1/*" = "$i" ]]; then continue; fi"来解决此问题。

第二种方法也可以通过使用"shopt -s nullglob"或在循环内部使用"[ -e "$i" ] || [ -L "$i" ] || continue"来修复,以避免输出"bla/*"。

因此,以上两种方法都可以实现在Bash中递归列出子目录的功能。

0