1

How can I eliminate redundant components in a path?

For example, I would like to transform

/foo/../foo/bar

to

/foo/bar
Mark Harrison
  • 297,451
  • 125
  • 333
  • 465
  • See [How do you normalize a file path in Bash?](http://stackoverflow.com/q/284662/4154375). – pjh Apr 05 '16 at 19:44
  • Note that on Unix-like systems that support symbolic links, '/X/../Y' is not always the same as '/Y'. In the example in this question, if you have directories '/bar/foo/bar' and '/bar/qux/bar', and '/foo' is a symlink to '/bar/qux', then '/foo/../foo/bar' is actually '/bar/foo/bar' and '/foo/bar' is actually '/bar/qux/bar'. All attempted solutions that just do textual substitutions on paths are wrong. (But it is ok to do that kind of thing on Windows because '..' means something different there.) – pjh Apr 05 '16 at 20:12

2 Answers2

2

Using gnu realpath:

p='/foo/../foo/bar'

realpath -m "$p"

Output:

/foo/bar

As per realpath --help:

-m, --canonicalize-missing   no components of the path need exist

You can also use more commonly available readlink (thanks to @pjh):

readlink -m "$p"
anubhava
  • 761,203
  • 64
  • 569
  • 643
0

You might pipe through something like: sed 's-/../foo/-/-g' to replace up/down reference in path names.

Muehlkreuz
  • 56
  • 3