代码之家  ›  专栏  ›  技术社区  ›  wonderfulthunk

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

  •  4
  • wonderfulthunk  · 技术社区  · 14 年前

    A.任何关于改进它的建议都是受欢迎的,特别是缺乏非连续的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
    
    3 回复  |  直到 14 年前
        1
  •  22
  •   Marc-André Lafortune    14 年前

    S 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"]
    
        2
  •  2
  •   Arkku    14 年前

    为什么不用呢 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"
    

    A.

    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('/')
    
        3
  •  1
  •   compie    14 年前

    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中使用相同的算法。