shell_string_expand.sf 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. #!/usr/bin/ruby
  2. # Daniel "Trizen" Șuteu
  3. # Date: 02 November 2017
  4. # https://github.com/trizen
  5. # A recursive algorithm for expanding a shell string.
  6. # It supports an arbitray number of nested curly braces, and it also
  7. # supports combining multiple individual groups, such as: "{a,b}{x,y}".
  8. # See also:
  9. # https://trizenx.blogspot.com/2012/03/expand-string.html
  10. func shell_string_expand(str) {
  11. if (var match = (str =~ /^(.*?)(?<brackets>\{(?:[^{}]++|(?&brackets))*\})(.*)\z/)) {
  12. var pt = __FUNC__(match[0]) .map { .split(',', -1) }
  13. var mt = __FUNC__(match[1].substr(1, -1)).map { .split(',', -1) }
  14. var st = __FUNC__(match[2]) .map { .split(',', -1) }
  15. return gather {
  16. [pt, st].cartesian { |prefix, suffix|
  17. var *P = prefix...
  18. var *S = suffix...
  19. var p = (P.pop \\ '')
  20. var s = (S.shift \\ '')
  21. take(P..., mt.map { .map { p + _ + s }... }..., S...)
  22. }
  23. }
  24. }
  25. return [str]
  26. }
  27. say shell_string_expand("{a,b{1,2,3},c}") #=> ["a", "b1", "b2", "b3", "c"]
  28. say shell_string_expand("{a,b{1,2,3}z,c}") #=> ["a", "b1z", "b2z", "b3z", "c"]
  29. say shell_string_expand("T{a,b{1,2,3},c}V") #=> ["TaV", "Tb1V", "Tb2V", "Tb3V", "TcV"]
  30. say shell_string_expand("{a,b}{x,y}") #=> ["ax", "bx", "ay", "by"]
  31. say shell_string_expand("{a,b,c}d") #=> ["ad", "bd", "cd"]
  32. say shell_string_expand("d{a,b,c}") #=> ["da", "db", "dc"]
  33. say shell_string_expand("{a,{b,c},d}") #=> ["a", "b", "c", "d"]
  34. say shell_string_expand("{a,{b,{c}},d}") #=> ["a", "b", "c", "d"]
  35. say shell_string_expand("{a,{{b},c},d}") #=> ["a", "b", "c", "d"]
  36. say shell_string_expand("{a,{P{b,z},c}S,d}") #=> ["a", "PbS", "PzS", "cS", "d"]
  37. say shell_string_expand("{a,S{{b,z}P,c},d}") #=> ["a", "SbP", "SzP", "Sc", "d"]
  38. say shell_string_expand("{f,t}{a,b}{x,z}") #=> ["fax", "tax", "fbx", "tbx", "faz", "taz", "fbz", "tbz"]
  39. say shell_string_expand("{f,t}{{a,b},{x,z}}") #=> ["fa", "ta", "fb", "tb", "fax", "tax", "fbx", "tbx", "faz", "taz", "fbz", "tbz"]
  40. say shell_string_expand("{a,b{1,f{x,y}}}") #=> ["a", "b1", "bfx", "bfy"]
  41. say shell_string_expand("{a,b{{x,y}f,1}}") #=> ["a", "bxf", "byf", "b1"]
  42. say shell_string_expand("{{{x,y}f,1}a,2}z") #=> ["xfaz", "yfaz", "1az", "2z"]
  43. say shell_string_expand("{{{x,y}f,1}a}z") #=> ["xfaz", "yfaz", "1az"]
  44. say shell_string_expand("{{{x,y}f,1}a,2}{z,b}") #=> ["xfaz", "yfaz", "1az", "2z", "xfab", "yfab", "1ab", "2b"]
  45. say shell_string_expand("{{{x,y}f,1}a,2}{z,{b,T}}") #=> ["xfaz", "yfaz", "1az", "2z", "xfab", "yfab", "1ab", "2b", "xfaT", "yfaT", "1aT", "2T"]
  46. say shell_string_expand("{K,P}{{{x,y}f,1}a,2}{z,{b,T}}") #=> ["Kxfaz", "Pxfaz", "Kyfaz", "Pyfaz", "K1az", "P1az", "K2z", "P2z", "Kxfab", "Pxfab", "Kyfab", "Pyfab", "K1ab", "P1ab", "K2b", "P2b", "KxfaT", "PxfaT", "KyfaT", "PyfaT", "K1aT", "P1aT", "K2T", "P2T"]
  47. say shell_string_expand("perl-{file-{which,basedir,copy-recursive},pathtools,path-class}") #=> ["perl-file-which", "perl-file-basedir", "perl-file-copy-recursive", "perl-pathtools", "perl-path-class"]