遍历目录中内容的正确方法

sta*_*her 17 ls shell-script wildcards dot-files for

我需要遍历目录中的每个文件。我看到的一种常见方法是使用以for file in *; do. 但是,我意识到它不包括隐藏文件(以“.”开头的文件)。另一个明显的方法是做类似的事情

for file in `ls -a`; do
Run Code Online (Sandbox Code Playgroud)

然而,迭代ls是一个坏主意,因为文件名中的空格会把一切搞砸。遍历目录并获取所有隐藏文件的正确方法是什么?

jim*_*mij 31

您只需要创建一个 glob 匹配文件列表,以空格分隔:

for file in .* *; do echo "$file"; done
Run Code Online (Sandbox Code Playgroud)

编辑

上面的可以使用大括号扩展以不同的形式重写

 for file in {.*,*}; do echo "$file"; done
Run Code Online (Sandbox Code Playgroud)

甚至更短: for file in {.,}*; do echo "$file"; done

添加所选文件的路径:

 for file in /path/{..?,.[!.],}*; do echo "$file"; done
Run Code Online (Sandbox Code Playgroud)

添加所选文件的路径:

 for file in /path/{.,}*; do echo "$file"; done
Run Code Online (Sandbox Code Playgroud)

如果您想变得复杂并从列表中删除通常不需要的...只需更改{.,}*{..?,.[!.],}*.

为了完整起见,值得一提的是,您还可以设置 dotglob 以将点文件与 pure *.

shopt -s dotglob
Run Code Online (Sandbox Code Playgroud)

zsh一个需要额外设置nullglob以防止在不匹配的情况下出错:

setopt nullglob
Run Code Online (Sandbox Code Playgroud)

或者,或者将 glob 限定符添加N到模式中:

for file in /path/{.,}*(N); do echo "$file"; done
Run Code Online (Sandbox Code Playgroud)

  • 这并不容易。`.*` 匹配 `.` 和 `..`(zsh 除外)。如果没有匹配的文件,`*` 保持为 `*`。`shopt -s gotglob` 仅在 bash 中。 (3认同)