简体   繁体   English

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

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

I'd like to match n digits the following way with grep or ls :我想用grepls以下列方式匹配 n 个数字:

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 grep or ls .我知道还有其他方法,但请注意,我想知道这是否可行: [[:digit:]]{6}使用grepls

Yes it's possible, using one of two methods:是的,可以使用以下两种方法之一:

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

Enabling Extended regular expression mode with -E means 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 failglob in 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 before passing it to ls , so ls isn't really doing much other than echoing those arguments.需要明确的是,当您执行ls ABCD[0-9][0-9][0-9][0-9][0-9][0-9].7z ,shell 会将 glob 扩展为一个列表将其传递给ls之前的参数,因此ls除了响应这些参数之外实际上并没有做太多事情。 This contrasts with the single quoted argument passed to grep , which is interpreted by grep as a regular expression.与此相反,传递给单引号参数grep ,其由解释grep为正则表达式。 Glob expressions and regular expressions are two different things, so you can't expect the syntax for them to be the same. Glob 表达式和正则表达式是两种不同的东西,所以你不能指望它们的语法是一样的。

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$'

You don't need grep for this with bash :使用bash不需要grep

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

The answer @Avinash Raj gave you is correct. @Avinash Raj 给你的答案是正确的。 But there is another way too.但也有另一种方式。 If you don't want to escape the braces(ie your grep expression is much longer and you can get lost in them) you can use egrep :如果您不想转义大括号(即您的 grep 表达式更长,您可能会迷失在其中),您可以使用egrep

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM