好吧,在立即将其作为重复项关闭之前,让我解释一下。我尝试过很多方法,例如:
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
作为杰夫·夏勒指出,
*
通常的工作方式类似于ls
- 它不会显示名称以.
(一段时间)。如果您使用的是 bash,并且您想要获取名称以.
, set(打开)嘘埃尔选择离子dotglob
与命令shopt -s dotglob
这将导致
*
工作像ls -A
- 它仍然不会显示.
和..
自己,但会显示以.
。您的问题提到“目录中的所有内容”。这是一个有些歧义的短语。如果您指的是(顶级)
/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
.您可以一次设置多个选项;例如,与
shopt -s dotglob globstar
有关选项的完整列表,请参阅 bash 文档。你可以你nset 选项与
shopt -u
.- 您应该始终引用所有 shell 变量引用(例如,
"$file"
),除非您有充分的理由不这样做,并且您确定您知道自己在做什么。
答案4
这种格式允许您从“ls”的所有列表和排序选项中进行选择:
ls -at $DIR | while read i; do echo $i; done