can regex capture groups be used in GNU find command?

With the GNU find command (GNU findutils 4.4.2), a regular expression can be used to search for files. For example:

$ find pool -regextype posix-extended -regex ".*/mypackage-([a-zA-Z0-9.]+-[0-9]{1,2})-x86_64.pkg.tar.xz+"

Is it possible to extract the capture group defined by that expression and use it in a -printf argument?

So, given a found file called pool/mypackage-1.4.9-1-x86_64.pkg.tar.xz, I would like to include the 1.4.9-1 part in a printf expression.

Is this possible?

Here is Solutions:

We have many solutions to this problem, But we recommend you to use the first solution because it is tested & true solution that will 100% work for you.

Solution 1

If you use

find pool -regextype posix-extended \
    -regex ".*/mypackage-([a-zA-Z0-9.]+-[0-9]{1,2})-x86_64\.pkg\.tar\.xz" \
    -printf '%f\n' |
  grep -Eo '[a-zA-Z0-9.]+-[0-9]{1,2}'

(assuming GNU grep as well), it should work for any path. The regex doesn’t allow for any newlines, so there’s no way to make it match for example a directory containing a similar name.

Solution 2

An alternative to l0b0’s fine answer (shorter, but potentially slightly less efficient):

Assuming a (recent) GNU sed:

find pool -print0 |
  sed -znE 's|.*/mypackage-([[:alnum:].]+-[0-9]{1,2})-x86_64\.pkg\.tar\.xz$|\1|p'|
  tr '\0' '\n'

Note the expensive part of find is the walking down the tree which it will have to do anyway whether you have -regex or not. So here, we’re doing the matching and reporting in sed instead.

Note: Use and implement solution 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from or, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply