在“ls”命令中使用通配符查找仅包含大写字母的文件

Aka*_*3di 1 ls wildcards case-sensitivity

因此,我一直在玩弄文件系统,并想知道如何列出/etc名称中仅包含大写字母的文件。我命令

ls *[A-Z]* 
Run Code Online (Sandbox Code Playgroud)

但是控制台也显示包含较低字符的文件。我只想使用ls命令。控制台程序语言环境是否相关?

根本原因是什么?

Eli*_*gan 7

[A-Z]不代表大写。它表示来自Ato 的字母Z,其中可能包括小写字母。通常你应该使用它[[:upper:]]。(即使没有extglob.,这也适用于 Bash 。)

[A-Z]匹配哪些字符取决于您的语言环境。

已经阐明,您希望在任何地方显示至少包含一个大写字符的所有文件名——不仅是完全由大写字母组成的文件名——而且当您使用 时ls *[A-Z]*,您会得到一些没有任何大写字符的文件名-其中的大小写字符。

当您的语言环境的字典顺序中包含大写和小写字母(例如,AaBbCcDd...)时,就会发生这种情况。尽管您可以设置其他语言环境(例如,LC_ALL=C),但最好的解决方案通常是编写一个专门匹配大写字母的模式。

哪些字符是大写字母也可能因语言环境而异,但大概如果某些内容在您的语言环境中是大写字母,那么您想要包含它。所以这可能是优点[[:upper:]]而不是缺点。

使用[[:upper:]]来代替。

大多数 Bourne 风格的 shell,例如 Bash,都支持 globs 中的 POSIX 字符类。此命令将列出/etc名称中至少有一个大写字母的条目:

ls -d /etc/*[[:upper:]]*
Run Code Online (Sandbox Code Playgroud)

您获得的某些条目可能是目录。如果您想显示它们的内容而不仅仅是列出目录,那么您可以删除该-d标志。您可能还想--在模式之前放置一个标志,以防您有以/etc开头的条目-。不过,您可能不会。(在脚本中,您通常希望在--此处使用。)

你可能不想要点文件,但如果你想要......

这不会显示以 开头的条目.。通常你不想展示它们。如果您确实需要它们,大多数 shell 允许您编写一个也匹配它们的单个 glob,或者将 globbing 配置为默认包含它们。.在 Bash 中自动包含前导条目的选项是dotglob,可以使用shopt -s dotglob. 对于其他外壳,请参阅 。或者您可以简单地为它们编写第二个 glob:

ls -d /etc/*[[:upper:]]* /etc/.*[[:upper:]]*
Run Code Online (Sandbox Code Playgroud)

最流行的 Bourne 风格的 shell 支持大括号扩展,所以你可以用更少的重复写得更紧凑:

ls -d /etc/{,.}*[[:upper:]]*
Run Code Online (Sandbox Code Playgroud)

在包括 Bash 在内的大多数 shell 中,当您编写两个单独的 glob 时,当其中一个不展开时,您将收到一条错误消息——因为大多数 shell 中的默认行为是不展开地传递它。但ls仍会显示与另一个匹配的条目。但是正如 Stéphane Chazelas 指出的那样在包括非常流行的 Zsh 在内的一些 shell 中,整个命令失败并且ls永远不会运行。如果您以交互方式使用 shell,这并不是真正有害,因为您可以修改命令再次运行它,但是这种结构不适合可移植脚本。如果您设置了failglobshell 选项,Bash 也会以这种方式运行。

您不需要为此进行扩展。

在 Bash 中,您不需要启用扩展 globbing 即可在 glob 模式中使用 POSIX 字符类。在我使用 Bash 4.3.48 的系统上:

ek@Io:~$ shopt extglob
extglob         off
ek@Io:~$ ls -d /etc/*[[:upper:]]*
/etc/ConsoleKit     /etc/LatexMk         /etc/ODBCDataSources  /etc/UPower
/etc/ImageMagick-6  /etc/NetworkManager  /etc/rcS.d            /etc/X11
Run Code Online (Sandbox Code Playgroud)

但是您确实需要它来匹配仅包含大写字母的文件名。

你怎么,如果你想匹配文件名包含扩展的需要为通配符是唯一的大写字母。然后你会使用+([[:upper:]])or *([[:upper:]]),那些是扩展的glob。

如果您正在使用 Bash,请参阅本文本指南GNU Bash 手册中的3.5.8.1 模式匹配以了解详细信息。另请参阅Stéphane Chazelas 的回答