Bash 正则表达式:如何使用“grep”或“ls”匹配 n 次

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32607721/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 13:34:13  来源:igfitidea点击:

Bash regex: how to match n times using 'grep' or 'ls'

regexbashgrepls

提问by thisismydesign

I'd like to match n digits the following way with grepor ls:

我想通过以下方式将 n 位数字与grepor匹配ls

echo "ABCD150915.7z" | grep "ABCD[[:digit:]]{6}.7z"

The above is not working and I've tried quite many ways now... How can this be done?

以上是行不通的,我现在已经尝试了很多方法......这怎么办?

I understand there are other ways, but please note that I want to know if this specifically is possible: [[:digit:]]and {6}using grepor ls.

我知道还有其他方法,但请注意,我想知道这是否可行:[[:digit:]]{6}使用grepls

回答by Tom Fenech

Yes it's possible, using one of two methods:

是的,可以使用以下两种方法之一:

echo "ABCD150915.7z" | grep -E "ABCD[[:digit:]]{6}.7z"

Enabling Extended regular expression mode with -Emeans that the curly braces are understood.

启用扩展正则表达式模式-E意味着可以理解花括号。

Alternatively, you can escape the curly braces:

或者,您可以转义花括号:

echo "ABCD150915.7z" | grep "ABCD[[:digit:]]\{6\}.7z"


If you want to list all files matching the pattern, you can use a glob expansion instead:

如果要列出与模式匹配的所有文件,可以改用 glob 扩展:

ls ABCD[0-9][0-9][0-9][0-9][0-9][0-9].7z

...and if you're thinking about looping through those files, you should do it like this:

...如果你正在考虑遍历这些文件,你应该这样做:

for file in ABCD[0-9][0-9][0-9][0-9][0-9][0-9].7z; do
    # stuff with "$file"
done

It's advised to enable failglobin either of these cases (use shopt -s failglob), so that when no files match the pattern, the command / loop isn't executed.

建议failglob在这两种情况中的任何一种情况下启用(使用shopt -s failglob),以便当没有文件与模式匹配时,不执行命令/循环。

The [0-9]in these examples isn't strictly the same as [[:digit:]], so if you require a strict match with anything considered a digit, then you should use that instead.

[0-9]这些例子中是不完全一样的[[:digit:]],所以如果你需要严格匹配任何被认为是数字的,那么你应该使用来代替。

To be clear, when you do ls ABCD[0-9][0-9][0-9][0-9][0-9][0-9].7z, the shell expands the glob into a list of arguments beforepassing it to ls, so lsisn't really doing much other than echoing those arguments. This contrasts with the single quoted argument passed to grep, which is interpreted by grepas a regular expression. Glob expressions and regular expressions are two different things, so you can't expect the syntax for them to be the same.

需要明确的是,当您这样做时ls ABCD[0-9][0-9][0-9][0-9][0-9][0-9].7z,shell 会将 glob 扩展为参数列表,然后再将其传递给ls,因此ls除了回显这些参数之外,实际上并没有做太多事情。这与传递给 的单引号参数形成对比grep,后者被解释grep为正则表达式。Glob 表达式和正则表达式是两种不同的东西,所以你不能指望它们的语法是一样的。

回答by Avinash Raj

You need to escape curly braces since basic grep uses BRE (Basic Regular Expression) in which \{\}acts like a repeatation quantifier where unescaped {}would match literal {, }braces.

您需要转义大括号,因为基本 grep 使用 BRE(基本正则表达式),其中的\{\}作用类似于重复量词,其中未转义的{}将匹配文字{,}大括号。

grep 'ABCD[[:digit:]]\{6\}\.7z'

Better to use anchors.

最好使用锚点。

grep '^ABCD[[:digit:]]\{6\}\.7z$'

回答by chepner

You don't need grepfor this with bash:

你不需要grep这个bash

foo=ABCD150915.7z
if [[ $foo =~ ABCD[[:digit:]]{6}.7z ]]; then
   echo "Successful match"
else
   echo "Match failed"
fi

回答by balinteu

The answer @Avinash Raj gave you is correct. But there is another way too. If you don't want to escape the braces(i.e your grep expression is much longer and you can get lost in them) you can use egrep:

@Avinash Raj 给你的答案是正确的。但也有另一种方式。如果您不想转义大括号(即您的 grep 表达式更长,您可能会迷失在它们中),您可以使用egrep

echo "ABCD150915.7z" | egrep "ABCD[[:digit:]]{6}.7z"