覆盖文件中的随机点

时间:2014-07-08 02:03:03

标签: ruby regex replace sed

我想基于正则表达式模式覆盖文件的某些部分。 ruby脚本将查找camelCase变量名称并将其转换为background-color之类的名称。我有一个要转换的所有变量的列表(键)以及需要更改的值(值):

variables = {
    "backgroundColor" => "background-color",
    "fontSize" => "font-size",
    "fontFamily" => "font-family",
    "fontColor" => "font-color",
    "formFont" => "form-font",
    "linkColor" => "link-color",
    "linkHoverColor" => "link-hover-color",
    "linkDecoration" => "link-decoration",
    "headingFamily" => "heading-family",
    "headingColor" => "heading-color",
    "baseWidth" => "base-width",
    "baseColWidth" => "base-col-width",
    "baseGutterWidth" => "base-gutter-width",
    "isFluid" => "is-fluid",
    "baseColCount" => "base-col-count",
    "tabletWidth" => "tablet-width",
    "mobilePortraitWidth" => "mobile-portrait-width",
    "mobileLandscapeWidth" => "mobile-landscape-width"
}

我有a working shell script

sed -i '' "s/${keys[i]}/${values[i]}/g" _MYconfig.scss

我正在尝试将其转换为Ruby。我尝试逐行读取文件,但文件中的行不对应于集合中的项目。这样的东西不起作用:

File.open("_skeleton.config.scss", "r+") do |file|
    file.each_line do |line|
        # use gsub here
    end
end

然后我从this gist中汲取灵感,并尝试:

variables.each do |key, value|
    %x(ruby -p -e "gsub /#{key}/, '#{value}' #{Dir.pwd}#{filename}")
end

但我似乎无法让它发挥作用。我无法弄清楚如何在sed这样的文件中随机写入。我无法弄清楚如何使用sed的ruby版本迭代variables。有什么想法吗?

2 个答案:

答案 0 :(得分:1)

对每个键使用此选项:

newkey = oldkey.gsub(/(?<=[a-z])(?=[A-Z])/, '-').downcase

<强>解释

  • 正则表达式通过使用lookbehind和lookahead匹配位于更改之间的位置(非字符)
  • (?<=[a-z])声明前一个字符是小写的
  • (?=[A-Z])断言下一个字符是大写的
  • gsub-
  • 替换该位置
  • 我们downcase结果

要在小写字母之前查看替换内容,请参阅此regex demo底部的替换。

答案 1 :(得分:0)

尝试这样的事情:

# read all lines of the file into an array
file_lines = File.readlines("_skeleton.config.scss", "r+")
new_file_lines = []

# gsub each line with all your matches
file_lines.each do |line|
   new_line = line
   variables.each do |key, value|
     new_line = new_line.gsub /#{key}/, value
   end
   new_file_lines << new_line
end

# then truncate the old file and write back the set of newlines
File.open("_skeleton.config.scss", "w") do |f|
   new_file_lines.each do |line|
      f.write line
   end
end

注意:未经测试,可能包含错误...