ruby each_line获得下一行

时间:2012-09-21 21:47:06

标签: ruby file-io

我有一个包含重复条目的文件。它看起来像

Los Angeles, 6
Los Angeles, 6 
New York, 31
New York, 31
New YOrk, 31
.
.
.

现在我想摆脱重复的数据。我尝试做的是使用each_line,看看行是否等于下一行,如果它们相同然后只是跳过,并写入新文件。问题是我应该如何获得该文件的下一行? 或者其他任何建议吗?

5 个答案:

答案 0 :(得分:4)

比较下一行是不必要的,因为您可以轻松查看当前行是否与前一行匹配:

file = File.open("filename", "r")
previous_line = nil
file.each_line { |line|
   if line == previous_line
     # duplicate line; ignore
   else
     # different; do whatever you want
   end

   # remember this line so we can compare against it
   previous_line = line
}

答案 1 :(得分:3)

如果重复项始终是连续的,那么willglynn的解决方案就可以了。否则,我认为最好的方法是将它们放入哈希值。

unique_list = {}

File.foreach(filename) do |line|
  unique_list[line] = 1
end

unique_list.each do |line|
  new_file.print line
end

答案 2 :(得分:2)

如果重复的行是连续的,你可以写:

lines = open("file.txt").each_line.chunk(&:downcase).lazy.map { |s, ss| ss.first }

downcase替换为您决定哪些字符串等效的函数。

答案 3 :(得分:1)

如果你可以从shell而不是Ruby那里做到这一点,并且你在* nix中工作,它会变得更容易。这是一个名为uniq的* nix工具。

根据您的示例输入,在文件 input.txt

Los Angeles, 6
Los Angeles, 6
New York, 31
New York, 31
New YOrk, 31

然后此命令将删除相邻的重复项并将结果打印到标准输出:

$ uniq input.txt
Los Angeles, 6
New York, 31
New YOrk, 31

您会注意到“纽约”第三个例子中的拼写错误导致它不被视为重复。

将结果发送到另一个文件:

$ uniq input.txt >output.txt
$ cat output.txt
Los Angeles, 6
New York, 31
New YOrk, 31

要修改原始文件,您不能将uniq的输出重定向到它 - 您将破坏uniq正在读取的输入。而是使用临时文件:

$ uniq input.txt >input.txt.tmp && cp input.txt.tmp input.txt
$ cat input.txt
Los Angeles, 6
New York, 31
New YOrk, 31

答案 4 :(得分:0)

以@ Anthony的答案为基础。我的想法是:

unique_list = {}
new_file=File.open('file2', "w")

File.foreach('filename') do |line|
  unique_list[line] = 1
end

unique_list.each do |key,value|
  new_file.puts key
end

每一行都成为散列的键,值为1.键是唯一的,因此重复只会覆盖最后一行。

输出,确保输入字符串末尾没有多余的空格是..

Los Angeles, 6
New York, 31
New YOrk, 31