Thanks for all the responses. I've got a mostly-bash solution based on Georgi's response. I had to clean it up a bit to handle .. and . properly. I'd like to figure out a way to use bash for the .., but for now it's just using sed.
Thanks again guys.
# Helper function for create_ml_includes
create_ml_includes-relative_between() {
local src="$(create_ml_includes-tidy_path ${1})"
local dst="$(create_ml_includes-tidy_path ${2})"
src=(${src//\// })
dst=(${dst//\// })
local i
for ((i=0; i<${#src[*]}; i++)); do
[ "${dst[i]}" != "${src[i]}" ] && break
done
local common=$i
for ((i=${#src[*]}; i>common; i--)); do
echo -n ../
done
for ((i=common; i<${#dst[*]}-1; i++)); do
echo -n ${dst[i]}/
done
echo -n ${dst[i]}
}
# Helper function for create_ml_includes
create_ml_includes-tidy_path() {
local removed="${1}"
if [ -n "${1}" ]; then
# Remove multiple slashes
while [ "${removed}" != "${removed/\/\//\/}" ]; do
removed=${removed/\/\//\/}
done
# Remove . directories
while [ "${removed}" != "${removed//\/.\//\/}" ]; do
removed=${removed//\/.\//\/}
done
[ "${removed##*/}" = "." ] && removed=${removed%/*}
# Removed .. directories
# I wonder if there's a non-trivial bashism for this one...
while [ "${removed}" != "$(echo ${removed} | sed -e
's:[^/]*/\.\./::')" ]; do
removed=$(echo ${removed} | sed -e 's:[^/]*/\.\./::')
done
# Remove trailing ..
removed=$(echo ${removed} | sed -e 's:/[^/]*/\.\.$::')
# Remove trailing /
[ "${removed##*/}" = "" ] && removed=${removed%/*}
echo ${removed}
fi
}
signature.asc
Description: This is a digitally signed message part
