簡體   English   中英

如何在ruby中查找不是當前文件的文件的文件路徑

[英]How to find the file path of file that is not the current file in ruby

我有一個充滿文件的文件夾,一些是txt文件,另一些是rb文件。 我想做的是使用main.rb文件中的代碼找到這些txt文件之一的路徑。

我想一個便宜的把戲是使用File.dirname(__FILE__) ,它將獲取當前rb文件的路徑,並且由於txt文件位於它可以使用的同一文件夾中。 但是上帝禁止txt文件不在同一個文件夾中,有沒有辦法仍然找到該txt文件的路徑?

一個簡單的Dir['c:/**/test.txt']將為您提供c:驅動器上所有test.txt文件的數組。

Dir['c:/**/*.txt']將為您提供所有擴展名為.txt的文件(可能很多)

但是在Windows中,有一個出色的工具可以搜索所有內容 ,它還有一個命令行版本,您可以在Ruby腳本中捕獲其輸出。 在大文件夾或驅動器上,這將比也可以使用的“ Dir”或“ Find”快得多。 我曾經做過,在這里,執行此操作的方法將需要安裝所有內容和命令行擴展。

require 'win32ole'
ES = 'C:\****\es\es.exe' # path to command line of Search Everything

def filelist path
  command = %Q{"#{ES}" -n 60 folder: -p #{path.join(" ").gsub('/','\\')}}
  list = []
  IO.popen(command+" 2>&1") do |pipe|
    while lijn = pipe.gets
      list << lijn.chomp
    end
  end
  list.join(',')
end

編輯

對於加里(Gary)來說,這是一種可以在操作系統中使用的方法,我在需要文件的最后修改時間的Sync工具中使用了此方法,而對於超過一千個文件而言,使用Ruby方法獲取該方法的速度太慢了。 它返回一個散列,其鍵是路徑,值是文件的最后修改日期。 它會根據需要跳過一些filesAdapt。

def list_files path
    folder, collection = "", {}
    IO.popen("dir /s /a:-d #{path}\\*.* 2>&1").each_line do |line|
      case line
        when /$RECYCLE.BIN|AlbumArt/ # skip these
        when /\d{8}T\d{6}/ # skip these
        when /desktop.ini|thumbs.db|sync_hist$/ # skip these
        when /^(\d{2}\/\d{2}\/\d{4}  \d{2}:\d{2})/
          modified = $1
          filename = line[36..-1].chomp
          collection["#{folder}\\#{filename}".downcase] = DateTime::strptime(modified, "%d/%m/%Y  %H:%M") rescue nil
        when /^ Map van / # Dutch for Folder of (my OS is in Dutch)
          folder = line[9..-1].chomp[path.length..-1]
      end
    end
    collection
  end

編輯2

今天,我不得不使用其中一種方法,因為我要處理的文件夾中包含大約30000個文件,而正常Ruby Dir發生問題之前的等待時間太長,並且在執行腳本時系統凍結了。

我記得這個答案,所以我想包括結果。

我做了一些基准測試,明確的贏家是Windows self。 我最初發布的方法中存在一些錯誤和附加功能,但是我不會更改它們,因為這樣就可以接受答案,而且附加功能(例如修改的時間)可能很有用。

取而代之的是,我用三種方法對它們的基准進行了測試,第四種方法是使用懶惰來查看變化(不多)。

require 'benchmark' 

STDOUT.sync = true
start_folder = 'c:/jpg'

def ruby_dir folder
  ruby_folder = folder.gsub('\\','/')
  files = []
  Dir.glob("#{ruby_folder}/**/*").each do |file|
    files << file if File.file? file
  end
  files
end

def ruby_dir_with_lazy folder
  ruby_folder = folder.gsub('\\','/')
  files = []
  Dir.glob("#{ruby_folder}/**/*").lazy.each do |file|
    if File.file? file
      files << file
    end
  end
  files
end

def os_dir path
  win_path = path.gsub('/','\\')
  files = []
  folder = win_path
  IO.popen("dir /s /a:-d #{win_path}\\*.* 2>&1").each_line do |line|
    case line
      when /^(\d{2}\/\d{2}\/\d{4}  \d{2}:\d{2})/
        filename = line[36..-1].chomp
        files << "#{folder}\\#{filename}"
      when /^ Map van / # Dutch for Folder of (my OS is in Dutch)
        folder = line[9..-1].chomp
    end
  end
  files
end

def es_dir path
  win_path = path.gsub('/','\\')
  files = []
  es = 'c:\everything\es\es.exe' # path to command line of Search Everything
  command = %Q{"#{es}" -p #{win_path}}
  IO.popen(command+" 2>&1").each_line do |line|
    files << line
  end
  files
end

Benchmark.bm do |x| 
  x.report("ruby_dir          ") { 3.times { ruby_dir(path) } }
  x.report("ruby_dir_with_lazy") { 3.times { ruby_dir_with_lazy(path) } }
  x.report("os_dir            ") { 3.times { os_dir(path) } } 
  x.report("es_dir            ") { 3.times { es_dir(path) } } 
end 

os_dir的結果是標准Ruby Dir的26倍

ruby_dir            1.747000  18.626000  20.373000 ( 20.397883)
ruby_dir_with_lazy  1.482000  18.799000  20.281000 ( 20.340853)
os_dir              0.608000   0.124000   0.732000 (  0.786640)
es_dir              1.202000   1.202000   2.404000 (  5.905093)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM