[Question]
  [
For this challenge, you will be given an absolute path, and a "new" path (which can be absolute or relative), and you need to return the final path.
For example, if your current directory was `/var/tmp/test`:
`my_dir` or `my_dir/` should return `/var/tmp/test/my_dir`
`../../my_dir` should return `/var/my_dir`
`/my_dir/./` should return `/my_dir`
`../../../../../` should return `/`
To be more pedantic:
* A directory is a non-empty string consisting of alphanumeric characters and the symbols `-`,`_`, or `.`
* **A path is a list of 0 or more directories**, separated using `/`. An absolute path starts with a `/`, a relative path does not. Paths can include an ending `/`.
You need to "resolve" the second path, given the first path.
The process of resolving is:
1. Test if the second path is relative. If so, then insert the absolute path's directories to the beginning of the second path.
2. If any of the directories is `..`, then remove it and the preceding directory. If it is the first directory, then simply remove it.
3. If any of the directories is `.`, then remove it.
4. Output the final absolute path. You should not output an ending `/`.
You do not need to handle incorrect input. The commands should work, whether or not the directories passed actually exist on your machine. You can assume that everything is a directory, even if it has an extension.
# Test cases
```
Absolute      New          Output
"/a/b/c"      "d"       -> "/a/b/c/d" 
"/a/b/c/"     "d"       -> "/a/b/c/d"
"/a/b/c/"     "d/"      -> "/a/b/c/d"
"/a/b/c"      "/d"      -> "/d"
"/a/b/c"      "/d/"     -> "/d"
"/../a/b/c/"  "d"       -> "/a/b/c/d"
"/a/../b/c/"  "d"       -> "/b/c/d"
"/a/b/../c"   "d"       -> "/a/c/d"
"/a/b/c/.."   "d"       -> "/a/b/d"
"/a/b/c/"     ".."      -> "/a/b"
"/a/b/c"      "../d"    -> "/a/b/d"
"/a/b/c"      "/../d"   -> "/d"
"/a/b/c"      ""        -> "/a/b/c"
"/a/b/c"      "."       -> "/a/b/c"
"/a/b/c"      "./d"     -> "/a/b/c/d"
"/a/b/c"      "/./d"    -> "/d"
"/a/b/c"      "d.txt"   -> "/a/b/c/d.txt"
"/a/b/c"      "d."      -> "/a/b/c/d."
"/a/b/c"      ".txt"    -> "/a/b/c/.txt"
"/a/b/c"      ".txt/d"  -> "/a/b/c/.txt/d"
"/a/b/."      "./././." -> "/a/b"
"/direc"      "tory"    -> "/direc/tory"
"/a-_.b/"     "__._-."  -> "/a-_.b/__._-."
"/a/b"        "../.."   -> "/"
"/a/b"        "../../.."-> "/"
"/a"          "../../.."-> "/"
"/"           ""        -> "/"
"/"           "a"       -> "/a"
"/.."         "a"       -> "/a"
"/."          ""        -> "/"
```
This is a [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), so make your submissions as short as possible in your favorite language!
  
[Answer]
## [Retina](https://github.com/m-ender/retina), 44 bytes
```
+`.+ /| |/\.?/
/
+1`/?[^/]*/\.\.|/\.?$
^$
/
```
Input is expected to be the two paths separated by a single space.
[Try it online!](http://retina.tryitonline.net/#code=JShHYAorYC4rIC98IHwvXC4_LwovCisxYC8_W14vXSovXC5cLnwvXC4_JAoKXiQKLw&input=L2EvYi9jIGQKL2EvYi9jLyBkCi9hL2IvYy8gZC8KL2EvYi9jIC9kCi9hL2IvYyAvZC8KLy4uL2EvYi9jLyBkCi9hLy4uL2IvYy8gZAovYS9iLy4uL2MgZAovYS9iL2MvLi4gZAovYS9iL2MvIC4uCi9hL2IvYyAuLi9kCi9hL2IvYyAvLi4vZAovYS9iL2MgCi9hL2IvYyAuCi9hL2IvYyAuL2QKL2EvYi9jIC8uL2QKL2EvYi9jIGQudHh0Ci9hL2IvYyBkLgovYS9iL2MgLnR4dAovYS9iL2MgLnR4dC9kCi9hL2IvLiAuLy4vLi8uCi9kaXJlYyB0b3J5Ci9hLV8uYi8gX18uXy0uCi9hL2IgLi4vLi4KL2EvYiAuLi8uLi8uLgovYSAuLi8uLi8uLgovLiAKL2EvYi9jIC4vLi4vLi8uLg) (The first line enables a linefeed-separated test suite.)
[Answer]
# Python, 53 bytes
```
from os.path import*;p=lambda a,n:normpath(join(a,n))
```
[Answer]
## Batch, ~~282~~ ~~281~~ ~~279~~ 276 bytes
```
@echo off
set a=\
set r=%~2
if "%r%"=="" set r=%~1
if not %r:~,1%==/ set r=%~1/%~2
for %%a in (%r:/= %)do call:x %%a
if not %a%==\ set a=%a:~,-1%
echo %a:\=/%
exit/b
:x
if %1==. exit/b
if not %1==.. set a=%a%%1\&exit/b
if not %a%==\ for %%a in (%a:~,-1%)do set a=%%~pa
```
Annoyingly Batch expressions don't generally like empty variables. Edit: Saved 1 byte thanks to @CᴏɴᴏʀO'Bʀɪᴇɴ and 2 bytes thanks to @EʀɪᴋᴛʜᴇGᴏʟғᴇʀ (and a bunch of bytes on other answers too, although alas uncredited).
[Answer]
# Python 2, ~~265~~ ~~260~~ 254 bytes
```
y=lambda:[x for x in raw_input().split("/")if x!=""and x!="."]
a=y();n=y();m=len(a)-1
while m>0:
 if a[m]==".."and m>0:del a[m];del a[m-1];m-=1
 elif a[m]=="..":del a[m]
 m-=1
for i in n:
 if i==".."and len(a)>0:del a[-1]
 else:a+=i,
print"/"+"/".join(a)
```
[Answer]
# Python, 142 137 bytes
```
def p(a,n,r=[],S="/"):
 for s in[s for s in((n[:1]!=S)*a+S+n).split(S)if"."!=s and s]:e=s!="..";r=[s]*e+r[1-e:]
 return S+S.join(r[::-1])
```
[Answer]
# Bash, 41 bytes
This bash script has the side effect of creating directories if they don't exist, but it should meet the requirements. Thanks [Karl](https://codegolf.stackexchange.com/questions/85479/directory-calculation#comment209832_85500) and [Neil](https://codegolf.stackexchange.com/questions/85479/directory-calculation#comment209847_85500) for your improvements.
```
mkdir -p $1;cd $1;mkdir -p $2;cd "$2";pwd
```
Usage: *bash getpath.sh "absolute" "new"*
If you don't like the stderr when second argument is an empty string, you can test for it as follows (48 bytes):
```
mkdir -p $1;cd $1;[ $2 ]&&mkdir -p $2&&cd $2;pwd
```
Previous 30 byte attempt (requires directories to exist):
~~*cd $1;[ $2 ]&&cd $2;echo `pwd`*~~
[Answer]
## C#, 43 bytes
```
(x,y)=>Path.GetFullPath(Path.Combine(x,y));
```
Saved 1 byte thanks to @aloisdg
`Path.Combine` puts the arguments together, and `Path.GetFullPath` resolves the `..\`s
[Answer]
# Node REPL, ~~8~~ 12 bytes
```
path.resolve
```
Luckily you don't have to `require()` standard modules in the REPL.
## Test Suite
<https://repl.it/Cclo/1>
(If the output at the end is `true`, it matched)
[Answer]
# Javascript, 210 bytes
```
function p(a,b){d='.';e=d+d;s='/';t='split';u='splice';r=(b[0]===s?[]:a[t](s)).concat(b[t](s));for(i=0;i<r.length;r[i]===e&&r[u](i?i-1:i,i?2:1)?(i&&i--):i++)(!r[i]||r[i]===d)&&r[u](i,1)&&i--;return s+r.join(s)}
```
[Here is test suite](https://repl.it/CdPQ/1)
With linebreaks instead of semicolons:
```
function p(a,b) {
    d='.'
    e=d+d
    s='/'
    t='split'
    u='splice'
    r=(b[0]===s?[]:a[t](s)).concat(b[t](s))
    for(i=0;i<r.length;r[i]===e&&r[u](i?i-1:i,i?2:1)?(i&&i--):i++)
        (!r[i]||r[i]===d)&&r[u](i,1)&&i--
    return s+r.join(s)
}
```
[Answer]
# Java 7, 83 bytes
```
String p(String a,String b){return Paths.get(a).resolve(b).normalize().toString();}
```
`normalize` is needed to deal with relative references. `add` is used to handle the second path starting with `/`, which `Paths.get(a, b)` won't handle as specified.
[Answer]
# Bash, 38 bytes
```
[[ $2 = /* ]]||p=$1
realpath -sm $p/$2
```
Doesn't require root privileges and makes no assumptions about existing or non-existing files, directories or symbolic links.
Test it on [Ideone](http://ideone.com/4z04WP).
### How it works
`[[ $2 = /* ]]` tests if the second command-line argument begins with `/`.
If it doesn't, the path is relative and `p=$1` sets variable **p** to the first command-line argument.
This way `$p/$2` is `/$2` if `$2` is an absolute path and `$1/$2` if it is a realtive one.
Finally, `realpath -sm $p/$2` prints the canonical absolute path of `$p/$2`. The `-s` switch makes *realpath* ignore symbolic links, and the `-m` switch missing components.
[Answer]
# Ruby, 16 bytes
Since apparently using [a method from the standard library](http://ruby-doc.org/core-2.3.1/File.html) is allowed:
```
File.expand_path
```
See the [test suite on repl.it](https://repl.it/CdLW/2).
[Answer]
# [GNU sed](https://www.gnu.org/software/sed/), ~~81~~ 59 + 1 = 60 bytes
+1 byte for `-r` flag. Expects input on STDIN separates by a single space.
```
s:.+ /::
s:/? :/:
:
s:/$|[^/]+/+\.\.|\.(/|$):\1:
t
s:^/*:/:
```
[Try it online!](https://tio.run/##VZDBDoIwDIbve4oePKiENl578UGcLMA4cBHDdtCEZ3cWEFazZPn@9u@fpqHzKQXGAojZBKYrMLFZ8DDdKroXVFi0OFk80nQ4sb2widKu6CzOlKimhlrwZgXSRD8E8pmkiPhnFqknRao8RJWIuOWIKWdqsRt20MbMHuMrZrG7VXXmbQAlZ3mGfD92LcRhfEurdNgQOIeuXDPmzVDjqhTLilDPR1h@@AzP2A@PkMrxCw "sed 4.2.2 – Try It Online")
## Explanation
```
s:.+ /::  # If the second argument starts with a slash, drop the first argument
s:/? :/:  # Join the first and second arguments with a slash, dropping duplicate slashes
:
  s:/$|[^/]+/+\.\.|\.(/|$):\1:  # Drop trailing slashes, resolve double and single dots
  t                             # If the above substitution was made, branch to :
s:^/*:/:  # Ensure output begins with a single slash
```
[Answer]
# [Zsh](https://www.zsh.org/), 15 bytes
```
a=$1/$2
<<<$a:a
```
The `:a` modifier does exactly this.
[Try it online!](https://tio.run/##dZBNCsMgEIX3nmIWbuPQLtv0LKIZIYHSQCr05/LWOLFNo1FB@Jz3xnnvex8e/XB1MDlDYMBCdwYaxd15aBqQBqQN5iIPKI@ibVtpTibQeHMBDVrsIC3iSzDDfYZrxgVINYbMlPrKV36RFszOtCv7KrXzl/Sw6RstqPgLwz8GUNHWGA@38St7kPJPX7CKXyorWXRcMsh90xZIw@SWOj9OL9Y2WlnOALVWulEszlPFeedsShZPhL/xM0yuq1hMTmKJOLEP "Zsh – Try It Online")
]