[英]How do I split a file by a grep with ruby?
我有一个包含很多代码的文件,我想将所有代码重构为自己的文件。 有问题的文件大约有30k行,所以我不想手动处理。
每个部分均始于:
module MyModule
(我改了名字)
是否有按标记分割文件的功能? 当我使用File.readlines
我找不到拆分数组的好方法。
我不在乎您如何命名它们。
我重构了您的代码。
File.read('lib/odin.rb').split(/module Odin/).each do |mod|
File.open("#{mod[/class (\w+)/, 1]}.rb", "w") do |f|
f.write("module Odin")
f.write(mod)
end
end
通过详细写出问题,我找到了答案。
我将其发布为答案,但是我会将答案授予具有更好解决方案的其他人:
big_file = File.readlines 'lib/odin.rb'
big_file.
join(' ').
split(/module Odin/).
map!{|w| w.prepend("module Odin\n") }.
each do |f|
name = "#{f.match(/class ([a-zA-Z]+)/)[1].underscore}.rb"
File.open(name, "w") do |n|
n.write(f)
end
end
我还想到了一种基于内容命名输出文件的好方法。 但我不在乎您如何命名它们。
Ruby有一个很棒的方法,它是Enumerable的一部分,称为slice_before
:
require 'pp'
modules = DATA.readlines.map(&:chomp).slice_before(/^module MyModule/).map{ |a| a.join("\n") }
pp modules
__END__
module MyModule
# 1 stuff
end
module MyModule
# 2 stuff
end
module MyModule
# 3 stuff
end
这是显示哪些modules
包含的输出:
["module MyModule\n # 1 stuff\nend\n", "module MyModule\n # 2 stuff\nend\n", "module MyModule\n # 3 stuff\nend"]
DATA
是从Perl继承的Ruby技巧。 __END__
之后的源文件中的__END__
均视为“数据”块的一部分,解释器在DATA
文件句柄中将其提供给正在运行的代码,其作用类似于数据文件。 这意味着我们可以像使用IO.readlines
一样在其上使用IO方法,例如readlines
。 我在这里使用__END__
和DATA
,因为它们对于简单的测试和简短的脚本很方便。
readlines
读取行时不会删除行尾,这是map(&:chomp)
所做的。 DATA.read.split("\\n")
将完成相同的操作。
slice_before
是使这项工作起作用的魔力。 它需要一个数组并对其进行遍历,从而创建子数组,该子数组在每次模式找到匹配时都开始。 接下来,只是在写入文件之前将子数组的内容重新合并为单个字符串的情况。
之后,您只需要遍历modules
,将每个modules
保存到另一个文件中:
modules.each.with_index(1) do |m, i|
File.write("module_#{ i }.rb", m)
end
with_index
是Enumerator中一个不错的小方法,当我们需要知道要处理的数组中的哪个项目时,该方法很有用。 它类似于each_with_index
不同之处each_with_index
我们可以指定起始偏移值,在这种情况下为1
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.