Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

regex

grep

bash

ls

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.

like image 927
thisismydesign Avatar asked Sep 16 '15 11:09

thisismydesign


People also ask

Can you use regex with grep?

You can also use the grep command to search for targets that are defined as patterns by using regular expressions. Regular expressions consist of letters and numbers, in addition to characters with special meaning to grep . These special characters, called metacharacters, also have special meaning to the system.

Can you use wildcards with grep?

The wildcard * (asterisk) can be a substitute for any number of letters, numbers, or characters. Note that the asterisk (*) works differently in grep. In grep the asterisk only matches multiples of the preceding character. The wildcard * can be a substitute for any number of letters, numbers, or characters.

How do you grep a pattern?

To find a pattern that is more than one word long, enclose the string with single or double quotation marks. The grep command can search for a string in groups of files. When it finds a pattern that matches in more than one file, it prints the name of the file, followed by a colon, then the line matching the pattern.

How does grep regex work?

grep is one of the most useful and powerful commands in Linux for text processing. grep searches one or more input files for lines that match a regular expression and writes each matching line to standard output.


1 Answers

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.

like image 103
Tom Fenech Avatar answered Sep 28 '22 10:09

Tom Fenech