私は(PERFORCEのデポ・パスのために)絶対パスへの変換このブラインドの相対を行うことができ、より良いですか?

StackOverflow https://stackoverflow.com/questions/2836825

質問

Iは、絶対パスにいくつかの相対パスを変換(即ち、ファイルシステムにアクセスすることなく、この場合、ソース管理サーバ)「盲目的に」必要があります。だから私は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で同じアルゴリズムを使用することができます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top