shell脚本中wildcharacter*的奇怪行为

Kau*_*eya 5 bash shell zsh wildcard echo

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

echo * | tr ' ' '\n'
Run Code Online (Sandbox Code Playgroud)

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

echo .* | tr ' ' '\n'
Run Code Online (Sandbox Code Playgroud)

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

因为.*是*
的理想输出的子集

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

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

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

因此echo*表现得像echo [^.]*

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

Jen*_*ens 6

shell glob *被定义为忽略隐藏文件,因此按预期工作.并且.*将扩大为隐藏文件.

有些shell允许通过选项更改此行为.例如,默认情况下zsh允许setopt dotglob变为不符合(对POSIX)和glob dotfiles.对于bash你可以使用shopt -s dotglob.但要注意脚本可能会出现故障,因为它们通常会假定用于globbing的POSIX行为.

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


Ola*_*che 3

文件名扩展中对此进行了介绍

\n\n
\n

当模式用于文件名扩展时,文件名开头或紧跟在斜杠后面的字符 \xe2\x80\x98.\xe2\x80\x99 必须显式匹配,除非设置了 shell 选项 dotglob。匹配文件名时,斜杠字符必须始终显式匹配。在其他情况下,\xe2\x80\x98.\xe2\x80\x99 字符不会被特殊处理。

\n
\n\n

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

\n\n
echo .* * | tr \' \' \'\\n\'\n
Run Code Online (Sandbox Code Playgroud)\n\n

或使用dotglob

\n\n
shopt -s dotglob\necho * | tr \' \' \'\\n\'\n
Run Code Online (Sandbox Code Playgroud)\n\n

这仍然排除了.and ..

\n