[英]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.