Regular expression to match a concatenation of fixed strings, and alternative expressions

I mean to match (with ls, rm, etc.) files with names test10 to test18, test30 to test38, test22 to test23, with a single regex, in bash.
I tried many variants around

$ ll "test([1,3][0-8]|22|23)" 

but I couldn’t make it work.
What is the correct way to do this?

In this context, shells uses glob patterns, not regular expressions1. In bash, you could use a ksh-style extended glob (enabled by default in an interactive bash shell – in a script, you will need to set with shopt -s extglob):

ls test@([13][0-8]|2[23])


ls test@(1[0-8]|2[23]|3[0-8])

In zsh, you could use numeric ranges instead (although it supports ksh-style extended globs as well):

ls test(<10-18>|<22-23>|<30-38>)

Alternatively, you could use brace expansion (in both bash and zsh) – but note this doesn’t actually perform matching so you will get errors unless all the named files are actually present:

ls test{{1,3}{0..8},22,23}

  1. Coincidentally, ([13][0-8]|2[23]) and (1[0-8]|2[23]|3[0-8]) are also valid extended regular expressions, so you could use them in a find expression for example:

    find . -maxdepth 1 -regextype posix-extended -regex '.*/test([13][0-8]|2[23])'
Answered By: steeldriver
Categories: Answers Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.