0

2 つの絶対ファイル パス (AおよびB) があります。Aの相対パスで変換したいB。Luaスクリプトを使用してどのように行うことができますか?

4

2 に答える 2

3

これを行うアルゴリズムは次のようになります。

  1. 両方のパスを標準形式に変換します。(つまり、ファイルシステムのルートから開始し、末尾のスラッシュや二重スラッシュなどはありません。)
  2. 両方のパスから、共通のプレフィックスを削除します。(例: からA="/a/b/c/d.txt" B="/a/b/e/f.txt"に移動A="c/d.txt" B="e/f.txt")
  3. 残りのパスをパス区切り記号で分割します。(だからあなたはで終わるでしょうA={"c", "d.txt"} B={"e", "f.txt"}
  4. 元のパスBが通常のファイルを指している場合は、 の最後の要素を削除しますB。ディレクトリを指している場合は、そのままにしておきます。(私たちの例では、あなたは得るでしょうB={"e"}
  5. B に残っているすべての項目について..、 の先頭に a を挿入しAます。(結果はA={"..", "c", "d.txt"})
  6. パスセパレーターを使用してコンテンツを結合しA、最終結果を取得します。"../c/d.txt"

これは、ライブラリなしで動作する非常に大まかな実装です。fromto同じである、または一方が他方のプレフィックスであるなどのエッジケースは処理しません。(これは、が に等しくなるため、これらのケースでは関数が確実に壊れることを意味します。) これは主に、私が怠け者だからです。また、コードがすでに少し長くなっており、これにより可読性がさらに損なわれるためです。mismatch0

-- to and from have to be in a canonical absolute form at 
-- this point
to = "/a/b/c/d.txt"
from = "/a/b/e/f.txt"

min_len = math.min(to:len(), from:len())
mismatch = 0
print(min_len)

for i = 1, min_len do
    if to:sub(i, i) ~= from:sub(i, i) then
        mismatch = i
        break
    end
end

-- handle edge cases here

-- the parts of `a` and `b` that differ
to_diff = to:sub(mismatch)
from_diff = from:sub(mismatch)

from_file = io.open(from)
from_is_dir = false
if (from_file) then
    -- check if `from` is a directory
    result, err_msg, err_no = from_file:read(0)
    if (err_no == 21) then -- EISDIR - `from` is a directory

end

result = ""
for slash in from_diff:gmatch("/") do
    result = result .. "../"
end
if from_is_dir then
    result = result .. "../"
end
result = result .. to_diff

print(result) --> ../c/d.txt
于 2012-11-05T01:13:48.410 に答える
2

pl.path.relpathPenlight ライブラリ ( doc / source ) から使用します。

于 2012-11-05T17:27:15.293 に答える