2

I've got a YAML file with nodes such as:

group:
  name: test
  permissions:
  - i.can.(create|delete)

I need to replace i.can.(create|delete) with i.can.create and i.can.delete (there are many instances).

How can I do this easily?

smci
  • 32,567
  • 20
  • 113
  • 146
mikroskeem
  • 37
  • 1
  • 9
  • 1
    So what's the exactly desired output? Each one in a different line? – fedorqui Mar 31 '14 at 14:19
  • Yes it is. I'm too lazy to modify by hand – mikroskeem Mar 31 '14 at 14:22
  • But I expect you are not that lazy to not even give a try to some sed commands? What did you try so far? – fedorqui Mar 31 '14 at 14:23
  • I tried to create python parser, but no idea how to parse it – mikroskeem Mar 31 '14 at 14:26
  • Don't reinvent the wheel, google for "python yaml" -- https://pypi.python.org/pypi/PyYAML/ – glenn jackman Mar 31 '14 at 14:44
  • i'm not reinventing wheel :D i just need to replace (this|and|that) parts – mikroskeem Mar 31 '14 at 14:59
  • Do you want to do this in YAML, AWK, SED, PERL, Python, or just any Linux command-line tool or scripting language, whatever's easiest? Do you want to do it for all arbitrary regex syntax (that's a very broad question), or only for the very simple example you gave: non-nested parentheses `(create|delete)`? With `[...]` or `['^...]` groups, multiple capture groups, back references, lookahead assertions, ... etc.? Your accepted answer is just a very manual kludge to the simplest possible way of expanding parentheses, not "regex-like notation" per your title. – smci Jun 03 '19 at 19:24
  • [Similar question in Python](https://stackoverflow.com/questions/55267366/expand-python-regex-to-list-of-all-possible-strings) – smci Jun 03 '19 at 19:29

2 Answers2

2

This might work for you (GNU sed):

sed -r 's/^(.*\bi\.can\.)\((create)\|(delete)\)/\1\2\n\1\3/' file
potong
  • 55,640
  • 6
  • 51
  • 83
  • +1; generalizing to _any 2_ fields inside `(...)` is easy - `sed -r 's/^(.*\bi\.can\.)\(([^)]+)\|([^)]+)\)/\1\2\n\1\3/' file` - but generalizing to a variable number of fields is not an option. OSX users: use `sed -E 's/^(.*[[:<:]]i\.can\.)\(([^)]+)\|([^)]+)\)/\1\2\'$'\n''\1\3/' file` – mklement0 Mar 31 '14 at 16:21
1

The idea is to replace all something(a|b|c|...) with lines somethinga somethingb etc.

awk seems to be suited here more than sed:

awk 'BEGIN { FS="[(|)]" ; OFS=""} /\(.*\)/ { for (field=2;field<NF;field++) {print $1,$field ;} ; next ; }1'

This will do what you wanted

Olivier Dulac
  • 3,695
  • 16
  • 31