5

在我的 shell 脚本中,我有以下代码

echo * | tr ' ' '\n'

在这里我注意到虽然我使用 * ,但它正在跳过隐藏文件(。*)之后我尝试了一个明显的改变

echo .* | tr ' ' '\n'

这解决了我的隐藏文件问题。但我只是对 * 的这种奇怪行为感到好奇

因为 .* 是 * 的子

  1. echo * -> 所有文件,包括隐藏文件

  2. echo .* -> 所有隐藏文件

  3. echo [^.]* -> 所有非隐藏文件(当前 echo *)

因此 echo * 的行为类似于 echo [^.]*

如何使用 echo 获取整个文件列表,包括隐藏文件。ls 和 dir 的输出类似,尽管 ls -a 给出了理想的输出

4

2 回答 2

6

shell glob*被定义为忽略隐藏文件,因此按预期工作。并且只会.*扩展到隐藏文件。

一些 shell 允许通过一个选项来改变这种行为。例如,默认情况下zsh允许setopt dotglob变得不符合(POSIX)以及全局点文件。对于 bash,您可以使用shopt -s dotglob. 但请注意,脚本可能会出现故障,因为它们通常假定 POSIX 行为进行通配。

获取所有文件的最佳选择是不要将 echo 与 glob 一起使用,但是例如find . -maxdepth 1(如果您对 echo 感到绝望,也许echo * .*会这样做,但如果任一 glob 与任何文件都不匹配,则会出现问题,在这种情况下 glob 模式可以保留)。

于 2013-02-27T07:27:17.390 回答
3

这在文件名扩展中有所介绍

当模式用于文件名扩展时,字符 '.' 除非设置了 shell 选项 dotglob,否则必须显式匹配文件名的开头或斜杠之后。匹配文件名时,斜杠字符必须始终显式匹配。在其他情况下,“。” 字符没有特殊处理。

如果要与.*一起包含*,则必须将两个参数都提供给 echo

echo .* * | tr ' ' '\n'

或使用dotglob

shopt -s dotglob
echo * | tr ' ' '\n'

仍然排除...虽然。

于 2013-02-27T07:31:15.497 回答