Ruby希望逐行读取文件并使用gsub删除特定部分

问题描述

我正在编写代码以逐行读取包含url的文本文件或csv文件,我想获取每个url的ID并打印或存储在文本文件中,但是当我这样做时,当我使用循环之前,我能够逐行打印它。谁能帮我这个忙。 下面是我的代码示例。

line_num=0
File.open('/Users/divyanshu/python_imdb/channels/url.txt').each do |line|
video_links = "#{line_num += 1} #{line}"
# puts video_links

for video_link in video_links 
 
    video_lin = video_link.gsub('https://www.youtube.com/watch?v=','')
    video_di = video_lin.gsub('?utm_source=komparify&utm_campaign=site&utm_medium=detailpage','')
    puts video_di
end 

这是我得到的错误

Traceback (most recent call last):
        2: from /Users/divyanshu/python_imdb/url_validation.rb:6:in `<main>'
        1: from /Users/divyanshu/python_imdb/url_validation.rb:6:in `each'
/Users/divyanshu/python_imdb/url_validation.rb:10:in `block in <main>': undefined method `each' for #<String:0x00007fef3d0907c0> (NoMethodError)

如果我只运行这部分代码,则可以正常工作。

line_num=0
File.open('/Users/divyanshu/python_imdb/channels/url.txt').each do |line|
    video_links = "#{line_num += 1} #{line}"
    puts video_links
end 

解决方法

字符串通常不#respond_to? :each

堆栈跟踪告诉您所有需要了解的内容:

#String:0x00007fef3d0907c0(NoMethodError)的未定义方法`each'

即使假设带有行尾空格的/channels /是文件路径的有效部分,File#open也会返回File对象而不是行集合。按照书面规定, video_links 是一个String,而不是诸如Hash或Array之类的集合,并且没有String#each方法。由于for-in循环是#each的语法糖,因此对象无法响应该方法。

取决于您是将整个文件插入行数组还是按行操作,应使用以下替代方法之一:

  1. File#each_line(来自IO)。例如:

    File.open("path/to/file").each_line
    
  2. File#readlines,也从IO继承。例如:

    File.readlines("path/to/file")
    
,

通过@Todd添加答案。正如我在评论中提到的,您的代码段中还有一个问题。 video_links变量属于String类。

  1. 它将仅包含文件的最后一行
  2. 您无法对其进行迭代

例如,一个file.txt如下:

one
two
three
four

和代码:

File.open('file.txt').each do |line|
  var = line
end

puts var
#=> "four"

因此,使用您的示例,您应该将变量video_links定义为(空)数组,并将文件行附加到要迭代的地方。

示例:

video_links = []

lines_in_file = File.readlines('/Users/divyanshu/python_imdb/channels/url.txt')

lines_in_file.each do |line|
  video_links.append line
end

video_links.each do |video_link|
  video_lin = video_link.gsub('https://www.youtube.com/watch?v=','')
  video_di = video_lin.gsub('?utm_source=komparify&utm_campaign=site&utm_medium=detailpage','')
  puts video_di
end