Разделить / путь / к / файлу

У меня есть явный путь к файлу:

/aaa/bbb/ccc/ddd/eee/fff.txt 

Мне нужно cd /aaa/bbb и выполнить операцию над ccc/ddd/eee/fff.txt .

Я понял первый бит:

 df_test=/aaa/bbb/ccc/ddd/eee/fff.txt cd $( echo ${df_test} | awk -F/ '{print "/"$2"/"$3}' ) 

Как мне затем отрубить первые два шага в пути и оперировать с остальными? Кроме того, я не буду знать заранее, насколько глубокими будут эти файлы. Я мог бы иметь

 /aaa/bbb/ccc/ddd.txt /aaa/bbb/ccc/ddd/eee/fff.txt /aaa/bbb/ccc/ddd/eee/fff/ggg/hhh/iii.txt 

Мне просто нужно изменить каталоги на / aaa / bbb и работать с оставшимся относительным путем.

В стандартной оболочке:

 $ path=/aaa/bbb/ccc/ddd/eee/fff.txt $ tail="${path#/*/*/}" $ head="${path%/$tail}" $ echo "$head" "$tail" /aaa/bbb ccc/ddd/eee/fff.txt 

"${path#/*/*/}" – это значение path но с удаленной (самой короткой) ведущей частью, совпадающей с /*/*/ , то есть вашей хвостовой частью. Тогда "${path%/$tail}" – это path с косой чертой и удаленной хвостовой частью.

Это приведет к неправильным результатам, если в пути недостаточно компонентов, поэтому вы можете сначала проверить это.

В качестве альтернативы, в Bash мы можем использовать совпадение регулярного выражения в [[ .. ]] и подбирать совпадающие fragmentы:

 $ if [[ $path =~ (/[^/]+/[^/]+)/(.*) ]]; then echo "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}" fi /aaa/bbb ccc/ddd/eee/fff.txt 

[[ ... ]] работает как условие, поэтому просто использовать if здесь, чтобы убедиться, что в пути достаточно компонентов.

Учитывая, что префикс является статическим, вы можете использовать расширение параметра, чтобы удалить его:

 df_test=/aaa/bbb/ccc/ddd/eee/fff/ggg/hhh/iii.txt cd /aaa/bbb operate=${df_test#/aaa/bbb} echo Operating on "$operate" 

Лично мне нравится cut это вместо этого:

 $ echo "/aaa/bbb/ccc/ddd/eee/fff.txt" | cut -d'/' -f4- ccc/ddd/eee/fff.txt 

Вам просто нужно настроить аргумент -f вы могли анализировать его в дереве каталогов.

Здесь показано, как избавиться от первых двух полей с помощью awk :

 $ echo "/aaa/bbb/ccc/ddd/eee/fff.txt" | awk -F'/' -v OFS='/' '{$1=$2=$3=""; print}' | sed 's#///##' ccc/ddd/eee/fff.txt