【问题标题】:How to summarize strings into shell globs如何将字符串汇总为 shell glob
【发布时间】:2017-04-21 03:07:13
【问题描述】:

是否有任何 Ruby 惯用语或流行的库可以将字符串合并到会生成它们的 shell glob 中?例如,给定字符串,

abc1
abc2
abc3

我想生成字符串abc{1..3}abc{1,2,3}。这很像在 IP 寻址中总结子网。

我想 Rubyesque 方法可能涉及对字符串进行排序,然后构建其组成字符的数组,将不重叠的字符递归地放入嵌套数组中。但是,如果已经有一些东西,我宁愿不重新发明那个轮子。

【问题讨论】:

  • 这听起来像是 X/Y 问题。您试图用这种方法解决的实际问题是什么?
  • 很抱歉让您失望了,但这里没有托词——这确实是我想要做的!我正在编写一些 ERB 模板来标准化问题措辞,并希望总结相关项目组(例如集群的成员)以提高人类的可读性。我不是想通过管道输出到外壳或类似的东西。措辞是为技术观众准备的,role01{a..c} 将是我们在第一个 role 集群中引用服务器 A 到 C 的最友好方式。
  • 你好,看来你需要找到最长的公共子串stackoverflow.com/questions/2158313/…,然后合并剩余的块

标签: ruby text


【解决方案1】:

我向Finding common string in array of strings (ruby)借用了公认的解决方案并使用了递归算法:

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

这很适合您的示例:

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

还涵盖了变量前缀等更复杂的情况:

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

甚至缺失值:

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

注意brace expansion 可能会生成不是文件的字符串。例如,最后一个示例扩展如下:

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

所以你必须小心使用输出。

【讨论】:

    猜你喜欢
    • 2017-03-22
    • 1970-01-01
    • 2017-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-05
    • 1970-01-01
    • 2019-11-25
    相关资源
    最近更新 更多