Skip to content

Instantly share code, notes, and snippets.

@chisophugis
Created July 7, 2014 22:45
Show Gist options
  • Save chisophugis/5d18832618fae94fba56 to your computer and use it in GitHub Desktop.
Save chisophugis/5d18832618fae94fba56 to your computer and use it in GitHub Desktop.
Braced shell expansion
import itertools
import re
import sys
try:
INPUT = sys.argv[1]
except:
print('Usage: {} <string-to-expand>'.format(sys.argv[0]), file=sys.stderr)
sys.exit(1)
def intersperse(l1, l2):
assert len(list(l1)) == len(list(l2)), "naive implementation"
for x1, x2 in zip(l1, l2):
yield x1
yield x2
# Check out the docs for how re.split handles parenthesized captures.
l = re.split(r'\{([^\}]*)\}', INPUT)
chunks, braceds = l[::2], l[1::2]
braceds = [x.split(',') for x in braceds]
# re.split always has 1 more "in between" piece (chunks)
# than match piece (braceds), so add a dummy entry at the end of braceds
# to make them the same length.
# This makes the code for "interspersing" the entries easier.
braceds.append([''])
for prod in itertools.product(*braceds):
print(''.join(intersperse(chunks, prod)))
@chisophugis
Copy link
Author

TODO: handle recursive expansion e.g. --foo{bar{baz,qux},quux}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment