如何在 bash 中匹配零个或多个模式实例?

How can I match zero or more instances of a pattern in bash?

我正在尝试遍历一堆文件前缀,从每个文件中寻找与给定模式匹配的一行。我提取并概括了几个示例,并在下面使用它们来说明我的问题。

我搜索了一行,开头可能有一些空格,后面是数字 1234,可能还有一些空格,然后是数字 98765。我知道感兴趣的文件以 l76.logsheet 开头我想从文件中提取以一个或多个数字结尾的行。但是,我想确保排除以其他任何内容结尾的文件(其中有太多选项无法合理使用 grep --exclude 选项)。这是我在 tcsh shell:

中的做法
tcsh% grep -E '^\s{0,}1234\s+98765' l76.logsheet[0-9]{0,}
l76.logsheet10:1234   98765       y  13:02:44     2

这是我再次搜索 98765 的另一个示例,但前面的数字和文件前缀不同:

tcsh% grep -E '^\s{0,}4321\s+98765' k43.logsheet[0-9]{0,}
k43.logsheet1:  4321    98765 y    13:06:38    14

效果很好,returns 正是我所需要的。

我的问题是 bash shell。重复相同的命令 returns 一个相当有趣的结果。用第一行,没有问题:

bash$ grep -E '^\s{0,}1234\s+98765' l76.logsheet[0-9]{0,}

哪个returns:

l76.logsheet10:1234   98765       y  13:02:44     2

但是第二个示例的结果在文件名末尾只有一位数字。这会导致 bash 在提供正确结果之前抛出错误:

bash$ grep -E '^\s{0,}4321\s+98765' k43.logsheet[0-9]{0,}
grep: k43.logsheet[0-9]0: No such file or directory
k43.logsheet1:  4321    98765 y    13:06:38    14

我的问题是,如何从 bash shell 中搜索以零个或多个先前模式结尾的文件?我有一个变通办法,但我正在寻找这个问题的实际答案,这可能会在未来为我(希望其他人)节省时间。

首先,确保 extglob 已设置:

shopt -s extglob

现在,我们可以用 *(...) 匹配零个或多个任意模式。例如,让我们创建一些文件并匹配它们:

$ touch logsheet logsheet2 logsheet23 logsheet234
$ echo logsheet*([0-9])
logsheet logsheet2 logsheet23 logsheet234

文档

根据 man bashbashextglob 一起提供以下功能:

?(pattern-list)
Matches zero or one occurrence of the given patterns

*(pattern-list)
Matches zero or more occurrences of the given patterns

+(pattern-list)
Matches one or more occurrences of the given patterns

@(pattern-list)
Matches one of the given patterns

!(pattern-list)
Matches anything except one of the given patterns