我有一个大文本文件,其中包含以下行:
“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”,...]
如何像我之前显示的那样输出它,只是数字和一行中的每个数字?
感谢。
答案 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")