0

我需要让 Perl 从 Linux 路径中删除相对路径组件。我发现了几个几乎可以满足我要求的功能,但是:

File::Spec->rel2abs做的太少了。它不能正确地将“..”解析为目录。

Cwd::realpath做得太多了。它解决了路径中的所有符号链接,这是我不想要的。

也许说明我希望这个函数如何表现的最好方法是发布一个 bash 日志,其中 FixPath 是一个假设命令,它提供所需的输出:

'/tmp/test'$ mkdir -p a/b/c1 a/b/c2
'/tmp/test'$ cd a
'/tmp/test/a'$ ln -s b link
'/tmp/test/a'$ ls
b  link
'/tmp/test/a'$ cd b
'/tmp/test/a/b'$ ls
c1  c2
'/tmp/test/a/b'$ FixPath . # rel2abs works here
===> /tmp/test/a/b
'/tmp/test/a/b'$ FixPath .. # realpath works here
===> /tmp/test/a
'/tmp/test/a/b'$ FixPath c1 # rel2abs works here
===> /tmp/test/a/b/c1
'/tmp/test/a/b'$ FixPath ../b # realpath works here
===> /tmp/test/a/b
'/tmp/test/a/b'$ FixPath ../link/c1 # neither one works here
===> /tmp/test/a/link/c1
'/tmp/test/a/b'$ FixPath missing # should work for nonexistent files
===> /tmp/test/a/b/missing
4

1 回答 1

-1

好吧,这就是我想出的:

sub mangle_path {
  # NOT PORTABLE
  # Attempt to remove relative components from a path - can return
  # incorrect results for paths like ../some_symlink/.. etc.

  my $path = shift;
  $path = getcwd . "/$path" if '/' ne substr $path, 0, 1;

  my @dirs = ();
  for(split '/', $path) {
    pop @dirs, next if $_ eq '..';
    push @dirs, $_ unless $_ eq '.' or $_ eq '';
  }
  return '/' . join '/', @dirs;
}

我知道这可能是不安全和无效的,但是这个例程的任何输入都将来自我在命令行上,它为我解决了几个棘手的用例。

于 2010-04-27T02:20:01.563 回答