从文件列表中获取数字,输出到Ruby中的另一个文件?

时间:2011-12-28 23:57:43

标签: ruby

我有一个大文本文件,其中包含以下行:

  

“X”:“452345230”

我想找到包含“X”的所有行,只取数字(不带引号),然后以这种方式输出另一个文件中的数字:

  

452349532

     

234523452

     

213412411

     

219456433

到目前为止我做的是:

myfile = File.open("myfile.txt")
x = [] 
myfile.grep(/"X"/) {|line|
   x << line.match( /"(\d{9})/ ).values_at( 1 )[0]
   puts x
   File.open("output.txt", 'w') {|f| f.write(x) }
}

它有效,但它产生的列表是这种形式:

  

[“23419230”,“2349345234”,...]

如何像我之前显示的那样输出它,只是数字和一行中的每个数字?

感谢。

3 个答案:

答案 0 :(得分:5)

这是一个不会让文件保持打开状态的解决方案:

File.open("output.txt", 'w') do |output|
    File.open("myfile.txt").each do |line|
        output.puts line[/\d{9}/] if line[/"X"/]
    end
end

答案 1 :(得分:2)

我无法重现你所看到的:

$ cat myfile.txt 
"X" : "452345230"
"X" : "452345231"
"X" : "452345232"
"X" : "452345233"
$ ./scanner.rb 
452345230
452345230
452345231
452345230
452345231
452345232
452345230
452345231
452345232
452345233
$ cat output.txt 
452345230452345231452345232452345233$ 

然而,我 注意到您的应用程序非常浪费并且可能没有达到预期的效果:您打开 output.txt,写一些内容,然后再次关闭它。下次在循环中打开时,会被覆盖。如果你的文件是1000行长,这不会那么糟糕,你只需要制作1000个文件。如果你的文件长度是1,000,000行,那么当你创建一个文件,写入文件然后再删除它一百万次时,这将代表相当可怕的性能损失。糟糕。

我重新编写了你的​​工具:

$ cat scanner.rb 
#!/usr/bin/ruby -w

myfile = File.open("myfile.txt")
output = File.open("output.txt", 'w')
myfile.grep(/"X"/) {|line|
   x = line.match( /"(\d{9})/ ).values_at( 1 )[0]
   puts x
   output.write(x + "\n")
}

这将打开每个文件,每次写入一个新行,然后在应用程序退出时关闭它们。根据这是您的应用程序的一小部分还是整个事情,这可能没问题。 (如果这只是程序的一小部分,那么当你完成它们时肯定会关闭文件。)

对于一百万条匹配的线路来说,这可能仍然是浪费 - 这些写入几乎肯定会直接传递给系统调用write(2),这将涉及一些开销。

你将运行多少这些?百万?十亿?如果需要更多细化,请随时询问......

答案 2 :(得分:2)

解决方案:

myfile = File.open("myfile.txt")

File.open("output.txt", 'w') do |output|
  content = myfile.lines.map { |line| line.scan(/^"X".*(\d{9})/) }.flatten.join("\n")

  output.write(content)
end

编辑:我更新了代码,减少了一点。如果上面的示例看起来很复杂,您还可以使用以下语句获取所需的数据(可能稍微清楚一下发生了什么):

content = myfile.lines.select { |line| line =~ /"X"/ }.map { |line| line.scan(/\d{9}/) }.join("\n")