Brace expansion with long common string

48 views Asked by At

I want to diff two similarly named files, so I want a Bash brace expression that expands to foo-averylongstring-bar baz-averylongstring-quux.

{foo,baz}-averylongstring-{bar,quux} unfortunately also creates two invalid combinations such as baz-averylongstring-bar. There is something about a dollar sign preventing expansion in the Bash documentation, but as I understand, ${...} is a variable expansion instead of brace expansion.

1

There are 1 answers

0
Kaz On

You can't do this with brace expansion. Each braced unit is independent and generates combinations in combination with the adjacent material. There is no such thing as two separate brace expansions working in parallel rather than as a cross-product. The shell doesn't have any parallel loops we could exploit.

I think the easiest solution would be to put the long, common string into a short variable:

x='averylong...string'
diff foo-$x-baz bar-$x-quux

If we have some sort of parallel iteration in a language, we can do things like:

1> `diff @(mapcar (ret `@1-longstring-@2`) '#"foo baz" '#"bar quux")`
"diff foo-longstring-bar baz-longstring-quux"

It would be nice to have a concise notation for this built into brace expansion. The only problem is that any way we try to work that in will break backward compatibility. Imagine that the square backets were not already used for character classes globbing. We could have it so that all items in square brackets belong to a parallel expansion:

[foo,baz]-longstring-[bar,quux]

Since we don't have square brackets, we could play some game with the braces, like using | to indicate expressions to be paralleled:

{|foo,baz}-longstring-{|bar,quux}

I have written an implementation of brace expansion, so this is an interesting possiblity, to me, for extending it. Because it's a library function, I could use flags to enable or disable the recognition of the | character.

Bash could do the same; have some shopt to enable such a thing.