我能做到这一点相对于绝对路径转换暗缝(Perforce的车厂路径)更好吗?
-
26-09-2019 - |
题
我需要“盲目地”(即,不访问文件系统,在这种情况下,源的控制服务器)的一些相对路径转换为绝对路径。所以我玩dotdots和索引。对于那些好奇我有别人的工具,有时会产出相对路径,以及性能方面的原因,我不想进入其中的路径所在的源控制服务器生成一个日志文件,以检查它们是否有效和更轻松地将它们转换成它们的绝对路径的等价物。
遍历文件夹阵列之上,并试图delete_at(指数)和delete_at的大多是一些变化(指数-1),但我的指数 -我已经通过了一些尝试得到它的工作(可能是愚蠢的)迭代不见了一直当我删除下自己的数组中的元素进行从,没有工作的多dotdots案件递增。改善它在一般或特别缺乏非连续dotdot支持将受到欢迎任何提示。
目前这正与我有限的例子,但我认为它可以改善。它不能处理非连续的“..”目录,我可能做了很多的浪费(且容易出错)的事情,我可能不需要做的,因为我是一个黑客攻击的一位。
我发现了很多使用其他语言的转换其他类型的相对路径的例子,但他们都不似乎符合我的情况。
这是我的示例路径,我需要转换,从:
//depot/foo/../bar/single.c
//depot/foo/docs/../../other/double.c
//depot/foo/usr/bin/../../../else/more/triple.c
为:
//depot/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
解决方案
让我们不要重新发明轮子... File.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
:
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解决方案,该想到的(也适用于你的例子):
absolute = []
relative = "//depot/foo/usr/bin/../../../else/more/triple.c".split('/')
relative.each { |d| if d == '..' then absolute.pop else absolute.push(d) end }
puts absolute.join('/')
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。
不隶属于 StackOverflow