Linux命令 – 循环浏览目录

评论 0 浏览 0 2019-09-11

1.概述

在很多情况下,我们可能想循环浏览某个文件夹中的所有目录。例如,我们可能想遍历所有的目录并在每个文件夹中运行一个特定的命令。

在本教程中,我们将看到我们如何使用Linux命令只循环浏览一个特定文件夹中的目录。在我们的例子中,我们将使用Bash shell,但这些命令也可能在其他POSIX shell中工作。

2.基本的for循环

让我们从Bash提供的基本循环结构之一开始。快速回顾一下,for循环被归类为一个迭代语句。它接受一个字符串列表作为输入,并允许对每一项重复执行代码,直到达到某个条件或达到列表的末尾。

现在我们已经了解了基本的for循环结构,在接下来的小节中,我们将解释两种不同的目录循环方式。

2.1.只有模式匹配的目录

我们将首先使用通配符模式来匹配多个文件,作为我们的for循环的输入

for dir in */; do
    echo "$dir"
done

让我们更详细地解释一下我们在上面的例子中所做的事情。

  • 我们使用一个标准的通配符glob模式‘*’来匹配所有文件。通过在后面添加一个‘/’,我们将只匹配目录
  • 然后,我们将每个目录分配给一个变量dir的值。
  • 在我们的简单例子中,我们然后在dodone之间执行echo命令,以简单地输出变量dir的值

然后我们回到顶部,抓取列表中的下一个目录,并重复进行,直到我们到达列表的末尾。

请注意,虽然优雅,但此解决方案有一个缺点。它假定我们在当前文件夹中至少有一个目录可用。 如果不存在目录,循环将执行一次并输出可能不需要的“*/”。

在下一个例子中,我们将看到一个应对这种情况的解决方案。

2.2.使用目录文件测试操作符号

现在,我们将看到如何使用文件测试操作符来确定我们列表中的文件项是否是一个目录。

for file in *; do
    if [ -d "$file" ]; then
        echo "$file"
    fi
done

在这个例子中,我们循环遍历当前目录中的所有文件。 然后使用标准的如果 语句,我们可以使用 -d flag 测试 file 变量是否是一个目录。

如果这个条件返回true,我们只需用echo命令输出file的值即可。

3.使用find命令

在这一节中,我们将看到如何使用find命令来打印出当前文件夹内的目录列表。

find . -maxdepth 1 -mindepth 1 -type d -printf '%f\n'

让我们更详细地看看这个命令,以正确地理解它。

  • 我们以‘.’开始,它被用来代表当前的目录
  • maxdepth参数表示从起点开始要下降到的目录层级
  • 然后,我们使用值为1的mindepth参数来处理除起点之外的所有文件–这意味着‘.’不会被包括在结果中。
  • -type d参数用于只包括目录
  • 最后,我们使用printf 只打印文件夹的名称,并为每个结果添加一个新的行。

这个例子可以作为一个简单的示范,但在现实中,我们可能想做的不仅仅是打印出目录的名称。在下一节中,我们将看到上述内容的一个变化。

4.结合findwhile read循环

在这个倒数第二个例子中,我们将看到如何像上一节那样使用查找命令,但这次是将它与while read循环结合起来,为我们找到的每个目录执行一个命令。

按照我们的for循环的例子,我们将简单地显示出文件夹的名称:

find . -maxdepth 1 -mindepth 1 -type d | while read dir; do
  echo "$dir"
done

在这个例子中,我们没有使用printf参数来输出文件夹的名称,而是将每个结果用管道送入一个while循环。我们把每个目录的值分配给一个叫做dir的变量,然后简单地echo这个变量的值。

5.使用findexec参数

在这最后一个例子中,我们将探索一个可以说是更优雅、更简洁的解决方案,为我们找到的每一个目录执行一个命令。

按照前面的例子,我们将简单地echo文件夹的名称,但这次使用了-exec参数

find . -maxdepth 1 -type d -exec echo {} \;

使用-exec动作,我们可以对选定的文件运行指定的命令。在我们的例子中,echo将用找到的文件名代替{}。命令的最后部分是一个转义的‘;’,只是意味着对每个文件执行一条echo命令。

6.结语

在这个快速教程中,我们描述了一些帮助我们在目录中循环的方法。

首先,我们使用标准的文件模式通配符探索了基本的for循环。后来,我们增加了一个目录文件测试。然后,我们展示了如何使用find命令实现类似的结果。

像往常一样,文章的完整源代码可以在GitHub上获得。

最后更新2022-11-28
0 个评论
标签