【问题标题】:Checking directory for file with certain extension检查具有特定扩展名的文件的目录
【发布时间】:2012-10-18 02:33:56
【问题描述】:

我正在尝试检查通过命令行输入的目录是否包含具有特定文件扩展名的文件。例如,如果我有一个文件夹“Folder1”,其中有另一个文件夹“Folder 2”,Folder2 包含几个文件,“test.asm”、“test.vm”、“test.tst”。我通过这样的命令行获取目录或文件

ruby translator.rb Folder1/Folder2

ruby translator.rb Folder1/Folder2/test.vm

我正在尝试做的是错误检查。我已经检查了输入是否是一个文件夹,现在我需要检查该文件夹是否实际上包含一个 .vm 文件。 到目前为止我所做的是:

require 'pathname'

pn = Pathname.new(ARGV[0])

if ARGV.size != 1
    puts "Proper usage is: ruby vmtranslator.rb file_directory\file.vm \nOR \nruby vmtranslator.rb file_directory\ where file_directory has multiple vm files test".split("\n")
elsif !pn.exist? && !pn.directory?
    puts "Something is wrong with the file"
    puts "Either try another file or check the file extension"
elsif pn.directory? && pn.children(false).extname.include?('.vm')
    puts "this should print if Folder1 is the folder, but not if Folder2 is.."
    vm_file1 = File.open("OPEN FILES WITH .vm AS EXTENSION)
elsif pn.exist? || pn.file?
    puts "this is right"
    vm_file = File.open(ARGV[0], "r")
    asm_file = File.new(ARGV[0].sub('.vm', '.asm'), "w")
end

所以应该首先检查是否只有1个参数,如果是,然后检查它是文件还是目录,否则输出错误,然后我正在做的是检查它是否是目录。如果是这样,我需要检查目录是否实际包含 .vm 文件。我试过pn.each_child {|f| f.extname == '.vm'},但它只检查第一个值,然后才返回true。除了设置一些布尔值之外,还有什么更简单的方法可以在返回 true 之前检查整个数组?

上面的一些代码还没有完成,我只是想问是否有任何方法可以检查目录中是否有特定扩展名的文件。到目前为止,我无法通过搜索找到任何内容。

【问题讨论】:

  • 考虑使用 -f 文件名和 -d 目录等参数并使用 optparse 解析它们。这不是一个好问题的原因是你的逻辑太复杂了。

标签: ruby file directory file-extension


【解决方案1】:
str = ARGV[0]

proc = ->(f) { puts "doing something with #{f.path}" }

if Dir.exists?(str)
  Dir.glob(File.join(str, File.join('**', '*.vm'))).each do |entry|
    proc[File.open(entry)]
  end
elsif File.exists?(str) && File.extname(str) == '.vm'
  proc[File.open(str)]
else
  puts "couldn't do anything with #{str}"
end

【讨论】:

  • 我喜欢 Dir.glob 行,但我并不真正理解您使用那里的 .each(&proc) 做什么。你能进一步解释一下吗?
  • & 运算符将Proc 转换为block,因此each 可以对其进行处理。这只是一个一次性的示例过程——我只是想快速“为每个文件条目做同样的事情”。您可以使用每个条目作为参数轻松调用“真实”方法。
  • @snowe2010: 但& 在 Ruby 中很多ablogaboutcode.com/2012/01/04/the-ampersand-operator-in-ruby
  • 好的,在尝试了你的代码之后,看起来File.join('**', '*.vm') 需要递归目录。如果该文件夹实际上不包含任何 .vm 文件,我实际上不希望它为 Folder1 返回 true。我可以删除那里的 ** 吗?
  • @snowe2010: Dir.glob(File.join(str, '*.vm')) 只会匹配str 目录中的文件
【解决方案2】:
Dir["Folder1/Folder2/*.vm"].empty?

如果Folder1/Folder2 中有任何.vm 文件,将返回false

【讨论】:

  • 我并没有具体说明,但是目录也可以只是Folder2/blah.vm,我能做到Dir[pn + "/*.vm"].empty?吗?
  • 我尝试了上述方法,但无法正常工作。问题是,用户可以输入任何路径,我需要检查路径是否实际包含一个 .vm 文件,或者它是否是一个 .vm 文件,如果没有/是否需要输出一个错误。
  • 我只是展示了您可能解决问题的方法,而不是为您解决整个问题。 Dir[str],相当于Dir.glob(str, 0),将返回一个匹配数组。 empty? 然后检查结果数组是否为空(即未找到匹配项)。在其他人的回复中,str 中的 "**" 匹配 0 个或多个中间目录,因此 "a/**/d" 匹配 /a/d/a/b/c/d。单个星号匹配非分隔符。人们使用File.join 是为了兼容——它只是插入一个斜杠(或反斜杠),它本身并没有什么魔力。
  • 是的,我看到了,但我仍然无法得到任何人所说的工作。我理解我无法让它发挥作用的原则。 Dir[File.join(str, "*.vm")) 不返回文件夹中的文件数组,如果文件夹是两个深。换句话说,Dir[File.join(str, File.join("**", "*.vm")) 有效是因为它检查了第二个目录,但它失败了,因为它还检查了父目录。我只需要检查字符串结尾的目录。没有别的。
【解决方案3】:
require 'pathname'

def directory_has_vm_files?(path)
  Dir.glob(path.join('*.vm')).size > 0
end

unless ARGV[0]
  puts %{
    Proper usage is:

    ruby vmtranslator.rb file_directory or file.vm

    OR

    ruby vmtranslator.rb file_directory
    where file_directory has multiple vm files
  }
else
  path = Pathname.new(ARGV[0])

  if path.exist?
    if path.file?
      if File.extname(path) == '.vm'
        puts "Valid VM file"
      else
        puts "Not a VM file"
      end
    else
      if directory_has_vm_files?(path)
        puts "Valid Directory - contains vm files"
      else
        puts "#{path} does not contain any VM file"
      end
    end
  else
    puts "Invalid path"
  end
end

【讨论】:

  • 我试过了,但我无法获取 directory_has_vm_files?工作方法。看来 path.join 功能不会那样工作。 pje的功能好像可以,但是我也不是很懂他的。
猜你喜欢
  • 1970-01-01
  • 2016-01-28
  • 1970-01-01
  • 2021-06-08
  • 2010-09-06
  • 2013-09-20
  • 2017-05-09
  • 1970-01-01
  • 2018-04-27
相关资源
最近更新 更多