Bash – Filename pattern for files that don’t yet exist

bash

Using a shell pattern such as {abc,def}xyz I can use it to create files (or directories) that don't yet exist:

$ ls
$ touch {abc,def}xyz
$ mkdir 123{a,b,c}
$ ls
123a  123b  123c  abcxyz  defxyz

What is puzzling me is how to create a subdirectory within each of a set of folders matching a pattern. For example, now that I have 123a, 123b, and 123c can I create a subdirectory in each of them without having to resort to listing them explicitly?

$ mkdir {12*}/rsnapshot         # Fails because 12* isn't a list
$ mkdir 12*/rnapshot            # Fails because 12*/rsnapshot doesn't exist
$ mkdir 123{a,b,c}/rsnapshot    # Succeeds but more complex than I'd like

The last example works, but requires me to list some part of every directory name in the {...} subclause. If I have a large number of directories this is a non-starter.

I've also got this line to work for simple names that don't contain spaces, but it's neither obvious nor elegant for a generalised solution:

echo -n 12* '' | xargs -r -d ' ' -I {} echo mkdir {}/rsnapshot

Is there a pattern template in bash that will allow me to create files or subdirectories within a large set of similarly named subdirectories without a loop?

Best Answer

dirs=( 123* )
set -- "${dirs[@]/%//deep/and deeper}"
mkdir -p "$@"

I don't think this needs an explanation...

Related Question