DIRNAME="/a/b/c/d/e"
D2=$(dirname "$DIRNAME")
DIRNAME2=$(basename "$D2")/$(basename "$DIRNAME")
Или в одну строку (но будьте осторожны со всеми двойными кавычками - легче разделить):
DIRNAME2=$(basename "$(dirname "$DIRNAME")")/$(basename "$DIRNAME")
Не пытайтесь играть в эту игру с обратными кавычками, если вы не сильно увлечены мазохизмом. И если в путях могут быть пробелы, используйте двойные кавычки вокруг имен переменных.
Это будет работать практически с любой оболочкой Korn Shell, а также с Bash. В bash
доступны и другие механизмы - другие ответы иллюстрируют некоторые из множества вариантов, хотя expr
также является решением старой школы (оно также присутствовало в Unix 7-го издания). Этот код, использующий обратные кавычки, работает и в оболочке Bash и Korn, но не в оболочке Heirloom (которая аналогична оболочке Unix System V Release 2/3/4, IIRC).
DIRNAME2=`basename "\`dirname \\"$DIRNAME\\"\`"`/`basename "$DIRNAME"`
(Два уровня вложенности не так уж и ужасны, но это довольно плохо; три уровня становятся действительно хитрыми!)
Тестирование
При тестировании манипуляции с именем пути, которая должна выдерживать пробелы в имени пути, стоит проверить с именем, содержащим двойные пробелы (а не одиночные пробелы или их использование). Например:
DIRNAME="/a b/ c d / ee ff / gg hh "
echo "DIRNAME=[[$DIRNAME]]"
echo "basename1=[[$(basename "$DIRNAME")]]"
echo "basename2=[[`basename \"$DIRNAME\"`]]"
echo
D2=$(dirname "$DIRNAME")
echo "D2=[[$D2]]"
DIRNAME2=$(basename "$D2")/$(basename "$DIRNAME")
echo "DIRNAME2=[[$DIRNAME2]]"
echo
DIRNAME3=$(basename "$(dirname "$DIRNAME")")/$(basename "$DIRNAME")
echo "DIRNAME3=[[$DIRNAME3]]"
DIRNAME4=`basename "\`dirname \\"$DIRNAME\\"\`"`/`basename "$DIRNAME"`
echo "DIRNAME4=[[$DIRNAME2]]"
Выход из этого:
DIRNAME=[[/a b/ c d / ee ff / gg hh ]]
basename1=[[ gg hh ]]
basename2=[[ gg hh ]]
D2=[[/a b/ c d / ee ff ]]
DIRNAME2=[[ ee ff / gg hh ]]
DIRNAME3=[[ ee ff / gg hh ]]
DIRNAME4=[[ ee ff / gg hh ]]