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 paths, but due to the ".." parent directory used in the second path I can't just pipe these to uniq
.
Is there a standard linux way to normalize directory paths?
My desired result is this:
>>> echo $MY_UNIQUE_PATHS
../Some/Path/
It seems python's relpath
can do it all for me...
#!/usr/bin/python
import 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 etc
print " ".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!
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 "$@"; do realpath "$p"; done | sort | uniq))
printf "%q " "${abspaths[@]}" #use printf to escape spaces etc
echo #newline after the above printf
#use python to get relative paths
relpath(){ 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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.