Frage

Ich muß „blind“ (das heißt, ohne den Zugriff auf das Dateisystem, in diesem Fall ist der Quellensteuerserver) umwandeln einige relativen Pfade absolute Pfade. Also ich bin mit dotdots und Indizes zu spielen. Für diejenigen, die neugierig sind, habe ich eine Log-Datei von jemand anderes Werkzeug erzeugt, dass manchmal Ausgänge relative Pfade und aus Leistungsgründen Ich will nicht den Source-Control-Server zugreifen, wo die Pfade befinden sich zu überprüfen, ob sie sind gültig und mehr leicht wandeln sie in ihrem absoluten Pfad Äquivalente.

Ich habe versucht, durch eine Reihe von (wahrscheinlich dumm) Iterationen gegangen es zur Arbeit zu kommen - meist ein paar Variationen über die Anordnung von Ordnern laufen und versuchen, delete_at (Index) und delete_at (Index-1), aber mein Index gehalten erhöht wird, während ich Elemente des Arrays aus unter mir zu löschen, die für Fälle mit mehreren dotdots nicht funktioniert hat. Irgendwelche Tipps, es im Allgemeinen oder speziell das Fehlen von nicht-konsekutiver dotdot Unterstützung zu verbessern wäre willkommen.

Zur Zeit ist dies die Arbeit mit meinen begrenzten Beispielen, aber ich denke, es verbessert werden könnte. Es kann nicht nicht-konsekutive behandeln ‚..‘ Verzeichnisse, und ich bin wahrscheinlich viel verschwenderischer (und fehleranfällig), Dinge zu tun, dass ich wahrscheinlich nicht tun müssen, weil ich ein bisschen wie ein Hack bin.

Ich habe viele Beispiele für die Umwandlung andere Arten von relativen Pfaden mit anderen Sprachen gefunden, aber keiner von ihnen schien meine Situation zu passen.

Das sind meine Beispiel Pfade, dass ich konvertieren müssen, aus:

//depot/foo/../bar/single.c

//depot/foo/docs/../../other/double.c

//depot/foo/usr/bin/../../../else/more/triple.c

zu:

//depot/bar/single.c

//depot/other/double.c

//depot/else/more/triple.c

Und mein Skript:

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
War es hilfreich?

Lösung

Lassen Sie sich nicht das Rad neu erfinden ... File.expand_path macht das für Sie:

[
  '//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"]

Andere Tipps

Warum nicht einfach File.expand_path verwenden:

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"

Für eine DIY-Lösung Arrays verwenden, das in den Sinn kommt (auch für Ihre Beispiele funktioniert):

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-Code:

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)

druckt:

//depot/bar/single.c
//depot/other/double.c
//depot/else/more/triple.c

Sie können den gleichen Algorithmus in Ruby verwenden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top