Bash 正则表达式:如何使用 'grep' 或 'ls' 匹配 n 次
Bash regex: how to match n times using 'grep' or 'ls'
我想通过以下方式将 n 个数字与 grep
或 ls
匹配:
echo "ABCD150915.7z" | grep "ABCD[[:digit:]]{6}.7z"
上面的方法不起作用,我已经尝试了很多方法...这怎么办?
我知道还有其他方法,但请注意,我想知道这是否可行:[[:digit:]]
和 {6}
使用 grep
或 ls
。
您需要转义花括号,因为基本 grep 使用 BRE(基本正则表达式),其中 \{\}
就像一个重复量词,其中未转义的 {}
将匹配文字 {
,}
大括号.
grep 'ABCD[[:digit:]]\{6\}\.7z'
最好使用锚点。
grep '^ABCD[[:digit:]]\{6\}\.7z$'
是的,可以使用以下两种方法之一:
echo "ABCD150915.7z" | grep -E "ABCD[[:digit:]]{6}.7z"
使用 -E
启用扩展正则表达式模式意味着可以理解大括号。
或者,您可以转义大括号:
echo "ABCD150915.7z" | grep "ABCD[[:digit:]]\{6\}.7z"
如果您想列出所有与该模式匹配的文件,您可以改用全局扩展:
ls ABCD[0-9][0-9][0-9][0-9][0-9][0-9].7z
...如果您正在考虑遍历这些文件,您应该这样做:
for file in ABCD[0-9][0-9][0-9][0-9][0-9][0-9].7z; do
# stuff with "$file"
done
建议在任何一种情况下启用failglob
(使用shopt -s failglob
),这样当没有文件匹配模式时,命令/循环不会被执行。
这些示例中的 [0-9]
与 [[:digit:]]
并不严格相同,因此如果您需要与任何被视为数字的内容进行严格匹配,则应改用它。
明确地说,当您执行 ls ABCD[0-9][0-9][0-9][0-9][0-9][0-9].7z
时,shell 将 glob 扩展为参数列表 ,然后 将其传递给 ls
,所以 ls
除了回应这些论点之外,并没有真正做太多事情。这与传递给 grep
的单引号参数形成对比,后者被 grep
解释为正则表达式。 Glob 表达式和正则表达式是两个不同的东西,因此您不能指望它们的语法相同。
@Avinash Raj 给你的答案是正确的。但是还有另一种方法。
如果你不想逃避大括号(即你的 grep 表达式更长,你可能会迷失在其中)你可以使用 egrep:
echo "ABCD150915.7z" | egrep "ABCD[[:digit:]]{6}.7z"
你不需要 grep
bash
:
foo=ABCD150915.7z
if [[ $foo =~ ABCD[[:digit:]]{6}.7z ]]; then
echo "Successful match"
else
echo "Match failed"
fi
我想通过以下方式将 n 个数字与 grep
或 ls
匹配:
echo "ABCD150915.7z" | grep "ABCD[[:digit:]]{6}.7z"
上面的方法不起作用,我已经尝试了很多方法...这怎么办?
我知道还有其他方法,但请注意,我想知道这是否可行:[[:digit:]]
和 {6}
使用 grep
或 ls
。
您需要转义花括号,因为基本 grep 使用 BRE(基本正则表达式),其中 \{\}
就像一个重复量词,其中未转义的 {}
将匹配文字 {
,}
大括号.
grep 'ABCD[[:digit:]]\{6\}\.7z'
最好使用锚点。
grep '^ABCD[[:digit:]]\{6\}\.7z$'
是的,可以使用以下两种方法之一:
echo "ABCD150915.7z" | grep -E "ABCD[[:digit:]]{6}.7z"
使用 -E
启用扩展正则表达式模式意味着可以理解大括号。
或者,您可以转义大括号:
echo "ABCD150915.7z" | grep "ABCD[[:digit:]]\{6\}.7z"
如果您想列出所有与该模式匹配的文件,您可以改用全局扩展:
ls ABCD[0-9][0-9][0-9][0-9][0-9][0-9].7z
...如果您正在考虑遍历这些文件,您应该这样做:
for file in ABCD[0-9][0-9][0-9][0-9][0-9][0-9].7z; do
# stuff with "$file"
done
建议在任何一种情况下启用failglob
(使用shopt -s failglob
),这样当没有文件匹配模式时,命令/循环不会被执行。
这些示例中的 [0-9]
与 [[:digit:]]
并不严格相同,因此如果您需要与任何被视为数字的内容进行严格匹配,则应改用它。
明确地说,当您执行 ls ABCD[0-9][0-9][0-9][0-9][0-9][0-9].7z
时,shell 将 glob 扩展为参数列表 ,然后 将其传递给 ls
,所以 ls
除了回应这些论点之外,并没有真正做太多事情。这与传递给 grep
的单引号参数形成对比,后者被 grep
解释为正则表达式。 Glob 表达式和正则表达式是两个不同的东西,因此您不能指望它们的语法相同。
@Avinash Raj 给你的答案是正确的。但是还有另一种方法。 如果你不想逃避大括号(即你的 grep 表达式更长,你可能会迷失在其中)你可以使用 egrep:
echo "ABCD150915.7z" | egrep "ABCD[[:digit:]]{6}.7z"
你不需要 grep
bash
:
foo=ABCD150915.7z
if [[ $foo =~ ABCD[[:digit:]]{6}.7z ]]; then
echo "Successful match"
else
echo "Match failed"
fi