Skip to content Skip to sidebar Skip to footer

Normalize Paths With Parent ".." Directories In The Middle In Bash Script

I have a list of paths stored in a bash variable, such as the following >>> MY_PATHS= ../Some/Path/ ../Some/Other/../Path/ I'd like to have a list of unique relative path

Solution 1:

It seems python's relpath can do it all for me...

#!/usr/bin/pythonimport sys, os, pipes
paths = sys.argv[1:]                 #arguments are a list of paths
paths = map(os.path.relpath, paths)  #"normalize" and convert to a relative path
paths = set(paths)                   #remove duplicates
paths = map(pipes.quote, paths)      #for filenames with spaces etcprint" ".join(paths)                #print result

Examples:

>>> normpath ../Some/Path/ ../Some/Other/../Path/
../Some/Path
>>> normpath ../Some/Path/ ../Some/Other/../Different\ Path/
'../Some/Different Path' ../Some/Path

If absolute paths are wanted, replace relpath with abspath.

Thanks, @devnull!

Solution 2:

Here's a version just in bash, except for printing relative paths it still uses python's magical relpath function (see this).

Note: Paths must exist otherwise realpath fails :(

#!/usr/bin/bash

IFS=$'\r\n'#so the arrays abspaths and relpaths are created with just newlines#expand to absolute paths and remove duplicates
abspaths=($(for p in"$@"; dorealpath"$p"; done | sort | uniq))
printf"%q ""${abspaths[@]}"#use printf to escape spaces etcecho#newline after the above printf#use python to get relative pathsrelpath(){ python -c "import os.path; print os.path.relpath('$1','${2:-$PWD}')" ; } 
relpaths=($(for p in"${abspaths[@]}"; do relpath "$p"; done))
printf"%q ""${relpaths[@]}"echo

Post a Comment for "Normalize Paths With Parent ".." Directories In The Middle In Bash Script"