循环遍历目录中的所有内容?

循环遍历目录中的所有内容?

好吧,在立即将其作为重复项关闭之前,让我解释一下。我尝试过很多方法,例如:

for d in /Applications ; do
   echo "$d"
done

但这会返回

/应用

而不是 /Applications 的内容。

我也尝试过:

#!/bin/bash
FILES=/Applications

for file in $FILES
do
   echo $file
done

这基本上是同一件事。不过,我注意到,当我这样做时:

#!/bin/bash

for file in *
do
    echo $file
done

它正确地反映了我的主文件夹中的所有文件夹。有人知道发生了什么事吗?

答案1

*被称为shell globbing(路径名扩展)运算符(?也是[]),当您不加引号地调用它时,它将扩展到当前目录中的所有文件(不带任何目录前缀)。如果您使用前缀eg /foo/*,它将扩展到目录中的所有文件/foo

请注意,它也用于匹配某些文件,例如仅匹配以当前目录开头foo和结尾的文件,请使用 glob 模式:bar

foo*bar

因此,for循环现在可以采用以下形式:

for f in foo*bar; do echo "$f"; done

阅读man您的 shell 页面以获取有关 shell 通配符的更多信息。

答案2

要迭代目录中的文件(和子目录),您可以使用

for file in /Applications/*
do
    echo "$file"
done

请注意,如果未找到匹配项,则file变量将包含/Applications/*字面字符串(带有星号),如果以下命令需要现有路径,则可能会导致错误。如果您不想在没有文件匹配的情况下执行任何操作,可以使用以下nullglob选项:

shopt -s nullglob
for file in /Applications/*
do
    echo "$file"
done

答案3

  1. 作为杰夫·夏勒指出*通常的工作方式类似于ls- 它不会显示名称以.(一段时间)。如果您使用的是 bash,并且您想要获取名称以., set(打开)埃尔选择离子dotglob与命令

    shopt -s dotglob
    

    这将导致*工作像ls -A- 它仍然不会显示...自己,但会显示以.

  2. 您的问题提到“目录中的所有内容”。这是一个有些歧义的短语。如果您指的是(顶级)/Applications目录中的所有内容,那么其他答案都可以。但如果你想要里面的一切/Applications (即/Applications目录中的所有内容及其子目录globstar),并且您使用的是 bash,请使用以下命令设置 shell 选项

    shopt -s globstar
    

    这会导致** 作为文件名组成部分意思是这里和下面的一切。所以

    for file in /Applications/**
    do
        echo "$file"
    done
    

    将列出目录中的所有对象(文件、目录等)/Applications

    请注意,它不能与同一组件级别的其他字符组合;即,你不能做类似的事情foo**bar。但是,您可以在**.例如,

    for file in /Applications/**/README
    

    将循环遍历树README中命名的所有文件/Applications,并且

    for file in /Applications/**/*.txt
    

    将找到所有名称以.txt.

  3. 您可以一次设置多个选项;例如,与

    shopt -s dotglob globstar
    

    有关选项的完整列表,请参阅 bash 文档。你可以nset 选项与shopt -u.

  4. 您应该始终引用所有 shell 变量引用(例如,"$file"),除非您有充分的理由不这样做,并且您确定您知道自己在做什么。

答案4

这种格式允许您从“ls”的所有列表和排序选项中进行选择:

ls -at $DIR | while read i; do echo $i; done

相关内容