相对于绝对路径转换(对于perforce depot路径),我可以做得更好吗?

won*_*unk 4 ruby algorithm relative-path absolute-path

我需要"盲目地"(即无法访问文件系统,在这种情况下是源控制服务器)将一些相对路径转换为绝对路径.所以我正在玩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
Run Code Online (Sandbox Code Playgroud)

Mar*_*une 22

让我们不要重新发明轮子...... 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"]
Run Code Online (Sandbox Code Playgroud)