I'd like to match n digits the following way with grep
or 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 grep
or ls
.
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.
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:
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.
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.
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. This contrasts with the single quoted argument passed to grep
, which is interpreted by grep
as 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.
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 'ABCD[[:digit:]]\{6\}\.7z'
Better to use anchors.
grep '^ABCD[[:digit:]]\{6\}\.7z$'
You don't need grep
for this with bash
:
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. 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 :
echo "ABCD150915.7z" | egrep "ABCD[[:digit:]]{6}.7z"
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.