Bash通配符n个数字

14

所以我在tmp目录中有以下文件:

 file.0
 file.1
 file.t9
 file.22
 file.4444

如果我只想列出以'.digits'(0、1、22、4444)结尾的文件,但不包括(t9),我可以尝试使用通配符,如下:

如果我希望只列出以“.digits”结尾的文件(0、1、22、4444),但不包括“t9”,我可以尝试使用通配符,例如:

 ls tmp/file.{[0-9],[0-9][0-9],[0-9][0-9][0-9],[0-9][0-9][0-9][0-9]}

然而,我遇到了丑陋错误导致出现以下结果

 ls: cannot access tmp/file.[0-9][0-9][0-9][0-9]: No such file or directory
 file.0
 file.1
 file.22
 file.4444

我也尝试过使用{0..999},但结果出现了相同类型的错误(并且数量更多)。有没有专家能够提供如何避免这些错误的线索呢?


1
请查看以下链接:https://dev59.com/h2Up5IYBdhLWcg3wVWev - Suvarna Pattayil
花括号扩展与模式匹配不同。它生成显式参数列表,而不是要匹配任何可能存在的模式。 - chepner
4个回答

32

至少在bash 4中,当启用extglob shell选项时:

shopt -s extglob
ls /tmp/file.+([0-9])

模式+([0-9])匹配一个或多个数字。

您可以在man bash模式匹配部分了解更多信息。

更新:

实际上,正如@chepner指出的那样,自从版本2.02引入extglob以来,在今天你遇到的几乎每个bash中,这应该都可以工作,除非你从石头里挖出你的发行版之类的东西。


我们不应该运行Bash 4,因为我收到了“...未预期的令牌'('”。 - Rafe
1
运行 shopt -s extglob 后再试一次! - janos
1
在我的Debian上,默认情况下这是可以正常工作的。假设你的系统管理员非常棒;-) - janos
2
extglob 在 2.02 版本中被引入。 - chepner
谢谢@chepner,好知道!(将此部分添加到我的答案中。) - janos
显示剩余2条评论

1
你可以使用ls命令列出所有文件,然后通过grep来筛选输出结果:
ls -1 | grep -E '\.[0-9]+$'

根据以下测试:
pax> printf 'file.0\nfile.1\nfile.t9\nfile.22\nfile.4444\n' | grep -E '\.[0-9]+$'
file.0
file.1
file.22
file.4444

使用-E可以获得扩展的正则表达式,这样+修饰符就会起作用。如果不可用,则可以使用\.[0-9][0-9]*$正则表达式。

1

另一种过滤特定扩展名文件的变体是使用带有谓词集的find命令:

find tmp/ -type f -iregex '^.*\.[0-9]+$'

-type谓词仅匹配文件,-iregex匹配以一个或多个数字结尾的名称 - 忽略名称的大小写。如果您想过滤以file开头的文件,则应改用以下内容:

find tmp/ -type f -iregex '^.*/file\.[0-9]+$'

最后,如果您不想为每个结果文件显示完整路径,请使用以下命令:
find tmp/ -type f -iregex '^.*/file\.[0-9]+$' -printf "%f\n"

0

另一个简单的解决方案是将标准错误重定向到/dev/null,以防止看到(即隐藏)“丑陋的错误”,方法是在末尾添加2> /dev/null。在您的示例中:

ls tmp/file.{[0-9],[0-9][0-9],[0-9][0-9][0-9],[0-9][0-9][0-9][0-9]} 2> /dev/null

这将为您提供所需的结果并隐藏任何错误。适用于将输出发送到stdout和错误发送到stderr的任何Linux命令或可执行文件。请注意,这不会影响命令返回状态($?),它只是抑制错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接