使用sed在Rakefile中编写xml标记

时间:2013-12-04 04:27:14

标签: ruby xml macos sed rakefile

我试图使用Rakefile预处理类似xml的文件,我要做的是添加一组xml标记。

以下sed是我所做的简短版本

sed -ig '/TARGET_STRING/{N;G;s/$/<key>KEY_NAME<\/key>/g;}' whateverfile.xml

这段代码在使用终端时工作得非常漂亮并且成功。

我将它们放入我制作的Rakefile中,就像这样:

desc 'setup pods archs'
task :setup_podsarchs => :setup_submodules do
    puts 'Altering xml...'.cyan
    `sed -ig '/TARGET_STRING/{N;G;s/$/<key>KEY_NAME<\/key>/g;}' whateverfile.xml`
end

执行rake后,会提示错误并终止任务

sed: 1: "/TARGET_STRING/{N;G;s/$/ ...": bad flag in substitute command: 'k'

我搜索了很长时间,无法找到有关转义<>Ruby字符的任何信息。


我的平台

  • 操作系统:Mac OS X 10.9
  • Ruby:2.0.0p247
  • rake:0.9.6
  • sed:7

更新

嗨,谢谢你们的回复非常快。

和@the Tin Man, 对于comment

我要做的是预处理Xcode项目文件(.pbxproj),该文件的结构为xml,

为简单起见,我只是在这里展示xml结构的例子:

<dict>
    <key>Key_ONE</key>
    <string>1</string>
</dict>

我要做的是找到KEY_ONE并在此之后添加另一个密钥:

<dict>
    <key>Key_ONE</key>
    <string>1</string>
    <key>Key_TWO</key>
    <string>2</string>
</dict>

2 个答案:

答案 0 :(得分:1)

使用正则表达式来处理除了最琐碎和受控制的解析之外的任何事情都会导致疯狂。使用Nokogiri,一个优秀的Ruby XML / HTML解析器。例如:

require 'nokogiri'

xml = <<EOT
<xml>
  <foo>foo</foo>
  <bar>bar</bar>
</xml>
EOT

doc = Nokogiri::XML(xml)

doc.at('foo').content = 'bar'
doc.at('bar')['class'] = 'cyan'

puts doc.to_xml

哪个输出:

<?xml version="1.0"?>
<xml>
  <foo>bar</foo>
  <bar class="cyan">bar</bar>
</xml>

请注意<foo>标记内的内容已更改,<bar>获取属性。

使用解析器的重要之处在于内容可以更改,标记参数可以更改,标记可以在标记内移动,标记可以跨多行分割,解析器也不关心,而正则表达式将喷出火焰并停止工作。

答案 1 :(得分:0)

解析器是更好的解决方案。

用于sed观点尝试

`sed -ig '/TARGET_STRING/{
    N
    s/$/\
<key>KEY_NAME<\/key>/
    }' whateverfile.xml`

G通常不需要,因为没有任何内容被加载 g也是不需要的,可能有1次替换