【问题标题】:How to convert absolute path in relative path using LUA?如何使用 LUA 在相对路径中转换绝对路径?
【发布时间】:2012-10-24 20:23:14
【问题描述】:

我有两个绝对文件路径(AB)。我想在B 的相对路径中转换A。我如何使用 Lua 脚本来做到这一点?

【问题讨论】:

  • 如果您提供AB 的示例以及您想要的输出,您的问题会更清楚。
  • 你是在问是否有一个特定的函数可以做到这一点,还是你在问一个在 Lua 中实现它的算法?

标签: lua path relative-path


【解决方案1】:

执行此操作的算法是:

  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={"..", "c", "d.txt"}
  6. 使用路径分隔符加入A的内容得到最终结果:"../c/d.txt"

这是一个非常粗略的实现,它不需要任何库。它不处理任何边缘情况,例如 fromto 相同,或者一个是另一个的前缀。 (我的意思是在这些情况下函数肯定会中断,因为mismatch 将等于0。)这主要是因为我很懒;也因为代码已经有点长了,这会更加损害可读性。

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

【讨论】:

    【解决方案2】:

    使用 Penlight 库中的 pl.path.relpath (doc / source)。

    【讨论】:

    • 使用现有的实现是个好主意,但似乎库依赖于lfs,这是一个二进制扩展。对于 OP,这可能是也可能不是问题 - 不确定使用他们的应用程序部署本机扩展程序是否繁琐。
    • 是的,LFS 是一个频繁的要求,但我应该精确它,谢谢你这样做;)
    猜你喜欢
    • 2017-08-01
    • 2011-11-07
    • 2011-05-02
    • 2019-08-20
    相关资源
    最近更新 更多