POSIX glob -- 如何匹配一个或多个 [:digit:]

use*_*471 6 linux posix glob sh

我想迭代foo.log它的日志轮换兄弟姐妹foo.1.gzfoo.2.gz从最新到最旧,代码不会被存在所迷惑foo.bar

令人高兴的是,logrotate命名事物时,从最新到最旧的顺序和字母顺序都是相同的。

我最初的尝试是for f in $(ls -t foo.*); do ...但是shellcheckIterating over ls output is fragile. Use globs. [SC2045]。另外,此代码匹配foo.bar不需要的内容。

但是如何将任意数量的数字与全局模式匹配呢?(或者这是不支持的?)我只知道如何明确列出每个数字。例如,以下处理 1 和 2 位数字并正确排除foo.1bar.gz但不处理foo.123.gz(并且我没有做正确的事情来导致globing 发生!)

for f in foo.log foo.[[:digit:]].gz foo.[[:digit:]][[:digit:]].gz; do ...

我可以假设没有人保留超过 100 个日志轮换的兄弟姐妹,但我不想这样做。

正在寻找符合 POSIX 标准的解决方案...

编辑:logrotate conf 会压缩某些文件,但不会压缩其他文件。所以并不是所有的兄弟姐妹都会以.gz.

Jam*_*den 6

全局模式不是正则表达式。语法请参见 glob(7)。

没有匹配一系列数字的全局模式。你可以近距离接触foo.[0-9]*.gz。如果它选择了一些您不想要的名称,您可以使用正则表达式将其过滤掉,也许类似于:

echo foo.[0-9]*.* | tr ' ' \\n | grep -E '[.][0-9]+([.]gz)?$' 
Run Code Online (Sandbox Code Playgroud)

考虑到您提出的约束,您可能可以使用 glob 模式并依赖 shell 进行排序。您可以使用 sort 检查您的 shell 是否按排序顺序呈现 glob 模式的文件

echo foo.[0-9]*.gz | tr \  \\n | sort -c
Run Code Online (Sandbox Code Playgroud)

但解析输出也是可以的,ls -t除非你非常严格。来自的指导shellcheck是一个很好的建议:许多人似乎希望ls在一个简单的 glob 就可以完成的情况下解析输出,并且依赖于ls在不同系统上以相同的方式运行会引发错误。也就是说,您只要求ls按时间对文件名进行排序,从而生成一列输出。您可能做的任何其他事情都更容易出错。