我一直试图找到解决方案。我已经找到了关于递归的问题和答案,但似乎没有任何东西适合这种特殊情况。
如果找到特定的搜索模式,我编写了一个应该遍历给定文件夹和所有子文件夹并重命名文件和文件夹的类。
一切按预期工作,可以调用replaceAllInDir,如果需要,它会替换文件和文件夹。然后,下一步是对给定文件夹中的所有子文件夹执行相同操作。 因此,可以识别子文件夹,并从内部调用replaceAllInDir。让我们假设所调用的特定子文件夹不包含任何子文件夹。我希望我们返回到父文件夹并继续查找其他子文件夹。但是控制不会返回到父调用方法,程序结束。
我知道解决实际用例的其他方法,但我无法解释ruby的行为。
class MultiFileAndFolderRename
attr_accessor :rootDir, :searchPattern, :replacePattern
def initialize(rootDir, searchPattern, replacePattern)
@rootDir = rootDir
@searchPattern = searchPattern
@replacePattern = replacePattern
end
def execute
replaceAllInDir(@rootDir)
end
def getValidDirEntries(dir)
dirList = Dir.entries(dir)
dirList.delete('.')
dirList.delete('..')
dirList
end
def replaceAllInDir(currentDir)
Dir.chdir(currentDir)
puts "Processing directory: " + Dir.pwd
dirList = getValidDirEntries(currentDir)
dirList.each { |dirEntry|
attemptRename(dirEntry)
}
dirList = getValidDirEntries(currentDir)
dirList.each { |dirEntry|
if File.directory?(dirEntry)
newDir = currentDir + '\\' + dirEntry
rntemp = MultiFileAndFolderRename.new(newDir, 'searchString', 'replaceString')
rntemp.replaceAllInDir(newDir)
end
}
end
def attemptRename(dirEntry)
if dirEntry.match(@searchPattern)
newname = dirEntry.to_s.sub(@searchPattern, @replacePattern)
FileUtils.mv(dirEntry.to_s, newname)
end
end
end
答案 0 :(得分:2)
你有一个错误。 replaceAllInDir()
的第一行是Dir.chdir()
。 chdir()
在全局范围内更改当前进程的目录。它不依赖于调用堆栈。因此,当您进入子目录并更改为该子目录时,即使您从递归返回,更改也将成为永久更改。
在调用replaceAllInDir()
后,您需要更改回正确的目录。例如:
...
dirList.each { |dirEntry|
if File.directory?(dirEntry)
....
rntemp.replaceAllInDir(newDir)
Dir.chdir(currentDir) # <- Restore us back to the correct directory
end
}
答案 1 :(得分:1)
我已经尝试过你的代码了,我发现了很多错误。也许如果你修复它们,你的想法就可以了。
MultiFileAndFolderRename.new(ARGV[0], ARGV[1], ARGV[2]).execute if __FILE__ == $0
这可以确保当你通过ruby rename.rb test old new
从shell调用ruby代码时,你的类将被实例化,并将相应地设置搜索和替换模式。getValidDirEntries(currentDir)
不起作用。如果你,例如。将其命名为目录测试,然后将当前目录更改为test,在目录中,getValidDirEntries('test')
将无法正常工作。MultiFileAndFolderRename
的新实例(这是不必要的)时,初始化程序的参数是错误的。相反,您应该使用当前实例,只需拨打self.replaceAllInDir(newDir)
而不是rntemp = MultiFileAndFolderRename.new(newDir, 'searchString', 'replaceString');rntemp.replaceAllInDir(newDir)
。我认为错误的实例化是它不能按预期工作的主要原因,但其他的也应该修复。