[英]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.