How to sum lines in shell globs

Are there any Ruby idioms or popular libraries for concatenating strings into the shell that generated them? For example, given the lines,

abc1
abc2
abc3

      

I want to create a string abc{1..3}

or abc{1,2,3}

. This is very similar to subnetting in IP addressing.

My guess is that Rubyesque's approach might involve sorting strings and then creating an array of their constituent characters, placing characters that do not overlap in nested arrays recursively. However, if something is already there, I would rather not reinvent this wheel.

+3


source to share


1 answer


I borrowed the accepted solution Find a common string in an array of strings (ruby) and used a recursive algorithm:

def longest_common_substr(strings)
  shortest = strings.min_by &:length
  maxlen = shortest.length
  maxlen.downto(0) do |len|
    0.upto(maxlen - len) do |start|
      substr = shortest[start,len]
      return substr if strings.all?{|str| str.include? substr }
    end
  end
end

def create_glob(files)
  return '' if files.compact.empty?

  stub=longest_common_substr(files)
  if stub.length == 0
    expansion = files.uniq.join(',')
    return '' if expansion == '' 
    return '{' + expansion + '}'
  end

  pre =  []
  post = []

  files.each do |file|
    i = file.index(stub)

    pre  << file[0, i] 
    post << file[i+stub.length..-1]
  end
  return create_glob(pre) + stub + create_glob(post)
end

      

This works well for your example:

puts create_glob(['abc1',
                  'abc2',
                  'abc3'
                 ])
#=> abc{1,2,3}

      

It also covers more complex cases like variable prefixes:

puts create_glob(['first.abc1',
                  'second.abc2',
                  'third.abc3'
                 ])
#=> {first,second,third}.abc{1,2,3}

      



And even the missing values:

puts create_glob(['.abc1',
                  'abc',
                  'abc3'
                 ])
#=> {.,}abc{1,,3}

      

Note extension extensions can create strings that are not files. For example, the last example expands as follows:

$ echo {.,}abc{1,,3}
.abc1 .abc .abc3 abc1 abc abc3

      

So, you have to be a little careful using inference.

0


source







All Articles