Ruby - 使用文件迭代任务

Ruby - iterate tasks with files

我正在努力用 Ruby 中的文件迭代任务。

(程序的目的 = 每周,我必须从学校系统中保存 40 个包含学生分数的 pdf 文件,然后手动将它们与上周的 pdf 进行比较,并更新一个电子表格,其中包含每个已通过目标的学生周。这是计算机的任务!)

我已经将一个 pdf 文件转换为文本,然后我的程序从文本文件中提取正确的数据并将每个学生变成一个数组 [姓名、分数、学院组]。然后它根据 csv 文件中的数据检查每个新数组,并添加任何新结果。

我的程序只处理一个 pdf 文件,因为我手动输入了:

f = File.open('output\agb summer report.txt')
agb = []
f.each_line do |line|
  agb.push line
end

但是我有一个完整的 pdf 文件文件夹,我想 运行 迭代地运行该程序。当我尝试将每个结果写入一个新命名的文件时,我也遇到了问题。

我尝试过使用变量和代码块,但我现在认为您不能以那种方式使用变量?

Dir.foreach('output') do |ea|
  f = File.open(ea)
  agb = []
  f.each_line do |line|
    agb.push line
  end
end

^ 这行不通。我也试过将目录名称导出到一个数组,并做类似的事情:

a.each do |ea|
  var = '\'output\' + ea + '\''
  f = File.open(var)
  agb = []
  f.each_line do |line|
    agb.push line
  end
end

我想我对 File 和 Dir 的对象类型从根本上感到困惑?我搜索了很多,还没有找到解决方案。我是 Ruby.

的新手

无论如何,我相信这是可以做到的——我目前的备份计划是用不同的细节复制我的程序 40 次,但这听起来很荒谬。请提供想法?

可以使用Dir.new("./")获取当前目录下的所有文件

所以像这样的东西应该有用。

file_names = Dir.new "./"

file_names.each do |file_name|
  if file_name.end_with? ".txt" 
    f = File.open(file_name)
    agb = []
    f.each_line do |line|
      agb.push line
    end
  end
end

顺便说一句,您可以只使用 agb = f.to_a 将文件内容转换为数组,每个元素都是文件中的一行。

file_names = Dir.new "./"   
file_names.each do |file_name|
  if file_name.end_with? ".txt" 
    f = File.open file_name
    agb = f.to_a
    # do whatever processing you need to do 
  end
end

你非常接近。 Dir.foreach() will return the name of the files whereas File.open() 想要路径。一个粗略的例子来说明这一点:

directory = 'example_directory'
Dir.foreach(directory) do |file|
  # Assuming Unix style filesystem, skip . and ..
  next if file.start_with? '.'

  # Simply puts the contents
  path = File.join(directory, file)
  puts File.read(path)
end

对文件列表使用 Globbing

您需要使用 Dir#glob 来获取您的文件列表。例如,给定 /tmp/pdf 中的三个 PDF 文件,您可以像这样使用 glob 收集它们:

Dir.glob('/tmp/pdf/*pdf')
# => ["/tmp/pdf/1.pdf", "/tmp/pdf/2.pdf", "/tmp/pdf/3.pdf"]

Dir.glob('/tmp/pdf/*pdf').class
# => Array

一旦你有了文件名列表,你就可以用类似的东西遍历它们:

Dir.glob('/tmp/pdf/*pdf').each do |pdf|
  text = %x(pdftotext "#{pdf}")
  # do something with your textual data
end

如果您使用的是 Windows 系统,那么您可能需要一个 gem,例如 pdf-reader 或来自 Ruby Toolbox that suits you better to actually parse the PDF. Regardless, you should use globbing to create a file list; what you do after that depends on what kind of data the file actually holds. IO#read 的其他东西,以及像 File# 这样的后代阅读是很好的起点。

处理文本文件

如果您处理的是文本文件而不是 PDF 文件,那么像这样的东西会让您入门:

Dir.glob('/tmp/pdf/*txt').each do |text|
  # Do something with your textual data. In this case, just
  # dump the files to standard output.
  p File.read(text)
end

如果您像这样分配目标文件夹 /path/to/your/folder/*.txt 它只会遍历文本文件。

2.2.0 :009 > target_folder = "/home/ziya/Desktop/etc3/example_folder/*.txt"
 => "/home/ziya/Desktop/etc3/example_folder/*.txt" 
2.2.0 :010 > Dir[target_folder].each do |texts|
2.2.0 :011 >     puts texts
2.2.0 :012?>   end
/home/ziya/Desktop/etc3/example_folder/ex4.txt
/home/ziya/Desktop/etc3/example_folder/ex3.txt
/home/ziya/Desktop/etc3/example_folder/ex2.txt
/home/ziya/Desktop/etc3/example_folder/ex1.txt

迭代文本文件是可以的

2.2.0 :002 > Dir[target_folder].each do |texts|
2.2.0 :003 >     File.open(texts, 'w') {|file| file.write("your content\n")}
2.2.0 :004?>   end

结果

2.2.0 :008 > system ("pwd")
/home/ziya/Desktop/etc3/example_folder
 => true 
2.2.0 :009 > system("for f in *.txt; do cat $f; done")
your content

your content

your content

your content