Ruby 中 2 个文件之间的匹配模式列表
Matching pattern list between 2 files in Ruby
我正在尝试打印 Input.txt 中包含 ValuesToSearch.txt 中的字符串的行。下面显示的我当前的脚本打印了正确的输出,
但是当我尝试使用 Input.txt 有 950 万行并且 ValuesToSearch.txt 有 300 行的实际数据时,处理非常非常慢。
如何修改脚本以获得更快的输出?谢谢
Input.txt
ID HM PRAO LN AC
1401144 851 2 45 32
1401145 6D2 4 45 32
1401146 B33 1 45 32
1401147 EEC 9 45 32
1401148 730 1 45 32
1401149 C08 3 45 32
1401150 B91 4 45 32
1401151 978 1 45 32
1401152 6A9 0 45 32
ValuesToSearch.txt
1401176
1401148
1401149
1401151
我的脚本:
ruby -e '
a=File.foreach("Input.txt").map {|l| l.split(" ")}
b=File.foreach("ValuesToSearch.txt").map {|l| l.split(" ")}.flatten
b.map{ |z|
a.map{ |i| puts i.join(" ") if i.include?(z) }
}'
1401148 730 1 45 32
1401149 C08 3 45 32
1401151 978 1 45 32
这个呢?
dict = File.read('/tmp/ValuesToSearch.txt').split.inject({}) do |acc, word|
acc[word] = true
acc
end
File.foreach('/tmp/Input.txt') do |line|
puts line if line.split.any? { |word| dict[word] }
end
在这种方法中,我使用哈希来存储 "values to search"。
因此,我们可以在 O(1) 中搜索(而不是 O(N))。
而且你不需要在Input.txt.
的话中重复两次
您可以在单次迭代中打印所需的行。
按照@tadman 的建议,将此脚本放入文件中并使用 ruby myscript.rb
.
执行它
首先让我们创建两个文件。
VTS_FName = "ValuesToSearch.txt"
vts_data = <<-_
1401176
1401148
1401149
1401151
_
File.write(VTS_FName, vts_data)
#=> 32
IT_FName = "Input.txt"
it_data = <<-_
ID HM PRAO LN AC
1401144 851 2 45 32
1401145 6D2 4 45 32
1401146 B33 1 45 32
1401147 EEC 9 45 32
1401148 730 1 45 32
1401149 C08 3 45 32
1401150 B91 4 45 32
1401151 978 1 45 32
1401152 6A9 0 45 32
_
File.write(IT_FName, it_data)
#=> 289
这里效率的关键是让VTS_FName
的内容成为集合而不是数组。
require 'set'
vts_set = File.readlines(VTS_FName).map(&:chomp).to_set
File.foreach(IT_FName) { |line| puts line if vts_set.include?(line[/\d+/]) }
1401148 730 1 45 32
1401149 C08 3 45 32
1401151 978 1 45 32
要保存匹配行而不是打印它们,请使用以下命令(在创建 vts_set
之后)。
File.foreach(IT_FName).with_object([]) { |line, arr|
arr << line.chomp if vts_set.include?(line[/\d+/]) }
#=> ["1401148 730 1 45 32",
# "1401149 C08 3 45 32",
# "1401151 978 1 45 32"]
我正在尝试打印 Input.txt 中包含 ValuesToSearch.txt 中的字符串的行。下面显示的我当前的脚本打印了正确的输出, 但是当我尝试使用 Input.txt 有 950 万行并且 ValuesToSearch.txt 有 300 行的实际数据时,处理非常非常慢。
如何修改脚本以获得更快的输出?谢谢
Input.txt
ID HM PRAO LN AC
1401144 851 2 45 32
1401145 6D2 4 45 32
1401146 B33 1 45 32
1401147 EEC 9 45 32
1401148 730 1 45 32
1401149 C08 3 45 32
1401150 B91 4 45 32
1401151 978 1 45 32
1401152 6A9 0 45 32
ValuesToSearch.txt
1401176
1401148
1401149
1401151
我的脚本:
ruby -e '
a=File.foreach("Input.txt").map {|l| l.split(" ")}
b=File.foreach("ValuesToSearch.txt").map {|l| l.split(" ")}.flatten
b.map{ |z|
a.map{ |i| puts i.join(" ") if i.include?(z) }
}'
1401148 730 1 45 32
1401149 C08 3 45 32
1401151 978 1 45 32
这个呢?
dict = File.read('/tmp/ValuesToSearch.txt').split.inject({}) do |acc, word|
acc[word] = true
acc
end
File.foreach('/tmp/Input.txt') do |line|
puts line if line.split.any? { |word| dict[word] }
end
在这种方法中,我使用哈希来存储 "values to search"。
因此,我们可以在 O(1) 中搜索(而不是 O(N))。
而且你不需要在Input.txt.
的话中重复两次
您可以在单次迭代中打印所需的行。
按照@tadman 的建议,将此脚本放入文件中并使用 ruby myscript.rb
.
首先让我们创建两个文件。
VTS_FName = "ValuesToSearch.txt"
vts_data = <<-_
1401176
1401148
1401149
1401151
_
File.write(VTS_FName, vts_data)
#=> 32
IT_FName = "Input.txt"
it_data = <<-_
ID HM PRAO LN AC
1401144 851 2 45 32
1401145 6D2 4 45 32
1401146 B33 1 45 32
1401147 EEC 9 45 32
1401148 730 1 45 32
1401149 C08 3 45 32
1401150 B91 4 45 32
1401151 978 1 45 32
1401152 6A9 0 45 32
_
File.write(IT_FName, it_data)
#=> 289
这里效率的关键是让VTS_FName
的内容成为集合而不是数组。
require 'set'
vts_set = File.readlines(VTS_FName).map(&:chomp).to_set
File.foreach(IT_FName) { |line| puts line if vts_set.include?(line[/\d+/]) }
1401148 730 1 45 32
1401149 C08 3 45 32
1401151 978 1 45 32
要保存匹配行而不是打印它们,请使用以下命令(在创建 vts_set
之后)。
File.foreach(IT_FName).with_object([]) { |line, arr|
arr << line.chomp if vts_set.include?(line[/\d+/]) }
#=> ["1401148 730 1 45 32",
# "1401149 C08 3 45 32",
# "1401151 978 1 45 32"]