Search code examples
linuxbashunixshell

How do you normalize a file path in Bash?


I want to transform /foo/bar/.. to /foo

Is there a bash command which does this?


Edit: in my practical case, the directory does exist.


Solution

  • if you're wanting to chomp part of a filename from the path, "dirname" and "basename" are your friends, and "realpath" is handy too.

    dirname /foo/bar/baz 
    # /foo/bar 
    basename /foo/bar/baz
    # baz
    dirname $( dirname  /foo/bar/baz  ) 
    # /foo 
    realpath ../foo
    # ../foo: No such file or directory
    realpath /tmp/../tmp/../tmp
    # /tmp
    

    realpath alternatives

    If realpath is not supported by your shell, you can try

    readlink -f /path/here/.. 
    

    Also

    readlink -m /path/there/../../ 
    

    Works the same as

    realpath -s /path/here/../../
    

    in that the path doesn't need to exist to be normalized.