【问题标题】:Reading specific lines from an external file in ruby IO从 ruby​​ IO 中的外部文件读取特定行
【发布时间】:2011-07-20 11:03:22
【问题描述】:

我有这个代码:

File.foreach("testfile.txt") { |line| print line }
lines = File.readlines("testfile.txt")
lines.each { |line| print line }

例如。我如何编辑它以从testfile.txt获取特定行?

$text2 = gets("some code to give me text on line 2 from textfile.txt").chomp

所以,我想运行一个程序来搜索 4 个任何人都可以编辑的不同变量。这些将位于一个单独的文件中,因此无需重写代码即可更改一组新搜索案例的测试。

假设我有一个看起来像这样的文档(我认为文本最简单,但可能是错误的):

Tea

Coffee

Hot Chocolate

Cookies

这就是文件中的全部内容。另一个文件(.rb)提取这些变量并在谷歌或其他任何地方搜索它们。如果代码以字节为单位读取,那么我将无法将变量更改为更长或更短的值。

让文件说出来是可行的

1:Tea

2:Coffee

3:Hot Chocolate

4:Cookies

只要代码只提取“茶”或“咖啡”而不是前面的数字。

【问题讨论】:

  • 避免使用 $ 全局变量,据我所知这在 Ruby 中被认为是不好的做法

标签: ruby io


【解决方案1】:

听起来你不想返回匹配某个模式的行,但你想按行号抓取。

解决方案 1:

def read_line_number(filename, number)
  return nil if number < 1
  line = File.readlines(filename)[number-1]
  line ? line.chomp : nil
end

解决方案 2a ​​- 效率更高,因为它不会尝试读取整个文件:

require 'english'
def read_line_number_1a(filename, number)
  found_line = nil
  File.foreach(filename) do |line|
    if $INPUT_LINE_NUMBER == number
      found_line = line.chomp
      break
    end
  end
  found_line
end

解决方案 2b - 也很有效,但风格更实用(虽然我没有检查 detect 是否会读取到文件结尾)

def read_line_number(filename, match_num)
  found_line, _idx =
    File.enum_for(:foreach, filename).each_with_index.detect do |_cur_line, idx|
      cur_line_num = idx+1
      cur_line_num == match_num
    end
  found_line.chomp
end

用法:

text = read_line_number("testfile.txt", 2)

【讨论】:

  • 文本文件应该采用什么格式才能使这个确切的代码工作?
  • @benjamin-shephard 我知道,如果您正在运行带有本机文本文件(即行尾)的本机 ruby​​ 解释器,它会正常工作;例如Windows (CRLF) 文本文件上的 Windows ruby​​ 将起作用。例如,如果您在 Linux 系统上使用 Windows 文本,则代码可能无法按原样运行。
【解决方案2】:

您可能想使用lines.grep "some string"。 或者,如果您确切知道您想要哪个行号 x,则只需 lines[x]

【讨论】:

    【解决方案3】:

    我的解决办法是:

    我的 testfile.txt 读取

    是的
    是的
    伙计,这太棒了

    我的 .rb 文件读取

    a = IO.readlines("testfile.txt").grep(/\w+/)
    puts "does it work...."
    sleep 2
    puts a[2]
    sleep 10

    【讨论】:

      【解决方案4】:
      def read_line_number(filename, number)
      f = File.open(filename)
      l = nil
      begin
        number.times do 
        l = f.readline.chomp
        end
      rescue
      puts "End of file reached"
      else
      f.close unless f.nil?
      return l  
      end
      end
      

      【讨论】:

      • 很抱歉:/ .....这段代码读取了 X.times 行,所以如果你想要一个已知的行,这个读取直到到达那里并且只返回最后一行读取..顺便说一句..是这么有效率?
      猜你喜欢
      • 2015-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多