我正在使用Ruby创建一些基本的工作辅助工具。我遇到了一个我不需要解决的问题,但好奇心对我来说是最好的。
我希望能够做的是搜索文件的内容,从特定行开始,找到第一个PREVIOUS字符串。
例如,如果我将以下文本保存在文件中,我希望能够从第4行开始搜索“CREATE PROCEDURE”并将此返回/输出“CREATE PROCEDURE sp_MERGE_TABLE”
CREATE PROCEDURE sp_MERGE_TABLE
AS
SOME HORRIBLE STATEMENT
HERE
CREATE PROCEDURE sp_SOMETHING_ELSE
AS
A DIFFERENT STATEMENT
HERE
搜索内容不是一个挑战,而是指定起始线 - 不知道。然后向后搜索......好吧......
任何帮助都赞赏!
TIA!
答案 0 :(得分:1)
我认为你必须逐行阅读文件行
然后将会工作
flag=true
if flag && line.include?("CREATE PROCEDURE")
puts line
flag=false
end
答案 1 :(得分:1)
如果性能不是一个大问题,你可以使用一个简单的循环:
# pseudocode
line_no = 0
while line_no < start_line
read line from file
if content_found in this line
last_seen = line_no # or file offset
end
line_no += 1
end
return last_seen
我担心你必须在文件中逐行工作,除非你有一些索引,指向行的开头。这会使循环变得更简单,但以向后方式处理文件会更难(除非您将整个文件保留在内存中)。
答案 2 :(得分:0)
修改强>
我只是有一个更好的主意,但无论如何我都要包括旧的解决方案。
向后搜索的好处意味着您只需要读取文件的第一个块,直到指定的行号。对于接近度,你越来越接近start_line,如果找到一个匹配,你就会忘记旧的...你仍然在开头阅读一些冗余数据,但至少它是O(n)
path = "path/to/file"
start_line = 20
search_string = "findme!"
#assuming file is at least start_line lines long
match_index = nil
f = File.new(path)
start_line.times do |i|
line = f.readline
match_index = i if line.include? search_string
end
puts "Matched #{search_string} on line #{match_index}"
当然,请记住,此文件的大小在回答您的问题时起着重要作用。
如果你想变得非常认真,你可以查看IO
类 - 看起来这可能是最终的解决方案。未经考验,只是一个想法。
f = File.new(path)
start_line.downto(0) do |i|
f.lineno = i
break if f.gets.include?(search_string)
end
<强>原始强>
对于详尽的解决方案,您可以尝试以下内容。缺点是您需要将整个文件读入内存,但如果它在没有匹配的情况下到达顶部则会考虑从下至上继续。未经测试。
path = "path/to/file"
start_line = 20
search_string = "findme!"
#get lines of the file into an array (chomp optional)
lines = File.readlines(path).map(&:chomp)
#"cut" the deck, as with playing cards, so start_line is first in the array
lines = lines.slice!(start_line..lines.length) + lines
#searching backwards can just be searching a reversed array forwards
lines.reverse!
#search through the reversed-array, for the first occurence
reverse_occurence = nil
lines.each_with_index do |line,index|
if line.include?(search_string)
reverse_occurence = index
break
end
end
#reverse_occurence is now either "nil" for no match, or a reversed-index
#also un-cut the array when calculating the index
if reverse_occurence
occurence = lines.size - reverse_occurence - 1 + start_line
line = lines[reverse_occurence]
puts "Matched #{search_string} on line #{occurence}"
puts line
end
答案 3 :(得分:0)
1)将整个文件读成字符串 2)反转文件数据字符串 3)反转搜索字符串 4)向前搜索。请记住匹配行尾而不是行首,并从头尾-N-而不是从N开始。
不是很快或没有效率,但它很优雅。或者至少聪明。