Ruby 相对于绝对路径转换(对于perforce depot路径),我能做得更好吗?
我需要“盲目”(即不访问文件系统,在本例中是源代码管理服务器)将一些相对路径转换为绝对路径。所以我在玩点和索引。对于那些好奇的人,我有一个由其他人的工具生成的日志文件,有时会输出相对路径,出于性能原因,我不想访问路径所在的源代码管理服务器,以检查它们是否有效,并更容易地将它们转换为绝对路径等价物 我已经经历了多次(可能是愚蠢的)迭代,试图让它正常工作-主要是在文件夹数组上迭代,并尝试在(索引)处删除和在(索引-1)处删除,但我的索引一直在增加,而我正在从我自己的下面删除数组中的元素,这对有多个点的案例不起作用。任何关于改进它的一般性或特别是缺少非连续dotdot支持的提示都是受欢迎的 目前,这是我的有限的例子,但我认为它可以改进。它不能处理非连续的“..”目录,我可能正在做很多浪费(和容易出错)的事情,我可能不需要做,因为我有点黑客 我发现了很多使用其他语言转换其他类型的相对路径的例子,但没有一个适合我的情况 以下是我需要转换的示例路径:Ruby 相对于绝对路径转换(对于perforce depot路径),我能做得更好吗?,ruby,algorithm,relative-path,absolute-path,Ruby,Algorithm,Relative Path,Absolute Path,我需要“盲目”(即不访问文件系统,在本例中是源代码管理服务器)将一些相对路径转换为绝对路径。所以我在玩点和索引。对于那些好奇的人,我有一个由其他人的工具生成的日志文件,有时会输出相对路径,出于性能原因,我不想访问路径所在的源代码管理服务器,以检查它们是否有效,并更容易地将它们转换为绝对路径等价物 我已经经历了多次(可能是愚蠢的)迭代,试图让它正常工作-主要是在文件夹数组上迭代,并尝试在(索引)处删除和在(索引-1)处删除,但我的索引一直在增加,而我正在从我自己的下面删除数组中的元素,这对有多个点
//depot/foo/./bar/single.c
//depot/foo/docs/./../other/double.c
//depot/foo/usr/bin/../../../../else/more/triple.c
致:
//仓库/bar/single.c
//depot/other/double.c
//depot/else/more/triple.c
还有我的剧本:
begin
paths = File.open(ARGV[0]).readlines
puts(paths)
new_paths = Array.new
paths.each { |path|
folders = path.split('/')
if ( folders.include?('..') )
num_dotdots = 0
first_dotdot = folders.index('..')
last_dotdot = folders.rindex('..')
folders.each { |item|
if ( item == '..' )
num_dotdots += 1
end
}
if ( first_dotdot and ( num_dotdots > 0 ) ) # this might be redundant?
folders.slice!(first_dotdot - num_dotdots..last_dotdot) # dependent on consecutive dotdots only
end
end
folders.map! { |elem|
if ( elem !~ /\n/ )
elem = elem + '/'
else
elem = elem
end
}
new_paths << folders.to_s
}
puts(new_paths)
end
开始
路径=文件.open(ARGV[0]).readlines
放置(路径)
新建路径=Array.new
路径。每个{路径|
文件夹=路径。拆分(“/”)
如果(文件夹。包括?(“…”))
num_dotdots=0
第一个点=folders.index(“..”)
last_dotdot=folders.rindex(“..”)
文件夹。每个{项目|
如果(项目==“…”)
num_dotdots+=1
结束
}
如果(first_dotdot和(num_dotdots>0))#这可能是多余的?
folders.slice!(first_dotdot-num_dotdots..last_dotdot)#仅依赖于连续的点
结束
结束
folders.map!{| elem|
if(elem!~/\n/)
elem=elem+'/'
其他的
元素=元素
结束
}
新路径Python代码:
paths = ['//depot/foo/../bar/single.c',
'//depot/foo/docs/../../other/double.c',
'//depot/foo/usr/bin/../../../else/more/triple.c']
def convert_path(path):
result = []
for item in path.split('/'):
if item == '..':
result.pop()
else:
result.append(item)
return '/'.join(result)
for path in paths:
print convert_path(path)
印刷品:
//depot/bar/single.c
//depot/other/double.c
//depot/else/more/triple.c
您可以在Ruby中使用相同的算法。为什么不使用文件。展开\u path
:
irb(main):001:0> File.expand_path("//depot/foo/../bar/single.c")
=> "//depot/bar/single.c"
irb(main):002:0> File.expand_path("//depot/foo/docs/../../other/double.c")
=> "//depot/other/double.c"
irb(main):003:0> File.expand_path("//depot/foo/usr/bin/../../../else/more/triple.c")
=> "//depot/else/more/triple.c"
对于使用阵列的DIY解决方案,我想到了这一点(也适用于您的示例):
让我们不要重新发明轮子…文件。expand_path
可以为您做到这一点:
[
'//depot/foo/../bar/single.c',
'//depot/foo/docs/../../other/double.c',
'//depot/foo/usr/bin/../../../else/more/triple.c'
].map {|p| File.expand_path(p) }
# ==> ["//depot/bar/single.c", "//depot/other/double.c", "//depot/else/more/triple.c"]
哇,我很惊讶File.expand_path没有出现在我为“ruby convert relative to absolute path”所做的众多谷歌搜索的第一页上。谢谢!
[
'//depot/foo/../bar/single.c',
'//depot/foo/docs/../../other/double.c',
'//depot/foo/usr/bin/../../../else/more/triple.c'
].map {|p| File.expand_path(p) }
# ==> ["//depot/bar/single.c", "//depot/other/double.c", "//depot/else/more/triple.c"]