Получить путь к файловому каталогу из пути к файлу

В Bash, если VAR="/home/me/mydir/file.c", как мне получить "/home/me/mydir"?

Ответ 1

dirname и basename - инструменты, которые вы ищете для извлечения компонентов пути:

$ VAR=/home/me/mydir/file.c

$ DIR=$(dirname "${VAR}")

$ echo "${DIR}"
/home/me/mydir

$ basename "${VAR}"
file.c

Они не являются внутренними командами Bash, но они являются частью стандарта POSIX (см. dirname, basename) и поэтому должны быть доступны на подавляющем большинстве систем, которые будут работать Bash.

Ответ 2

$ export VAR=/home/me/mydir/file.c
$ export DIR=${VAR%/*}
$ echo "${DIR}"
/home/me/mydir

$ echo "${VAR##*/}"
file.c

Чтобы избежать зависимости от basename и dirname

Ответ 3

В соответствующей заметке, если у вас есть только имя файла или относительный путь, dirname сам по себе не поможет. Для меня ответ оказался readlink.

fname='txtfile'    
echo $(dirname "$fname")                # output: .
echo $(readlink -f "$fname")            # output: /home/me/work/txtfile

Затем вы можете объединить эти два, чтобы получить только каталог.

echo $(dirname $(readlink -f "$fname")) # output: /home/me/work

Ответ 4

Если вы хотите, чтобы файлы-мишени были символическими, сначала вы можете проверить их и получить исходный файл. Предложение if может помочь вам.

if [ -h $file ]
then
 base=$(dirname $(readlink $file))
else
 base=$(dirname $file)
fi

Ответ 5

Я играл с этим и придумал альтернативу.

$ VAR=/home/me/mydir/file.c

$ DIR=`echo $VAR |xargs dirname`

$ echo $DIR
/home/me/mydir

Часть, которую мне понравилась, было легко расширить резервную копию дерева:

$ DIR=`echo $VAR |xargs dirname |xargs dirname |xargs dirname`

$ echo $DIR
/home

Ответ 6

Вот script, который я использовал для рекурсивной обрезки. Замените $1 на нужный вам каталог.

BASEDIR="$1"
IFS=$'\n'
cd $BASEDIR
 for f in $(find . -type f -name ' *')
 do 
	DIR=$(dirname "$f")
	DIR=${DIR:1}
	cd $BASEDIR$DIR
    rename 's/^ *//' *
 done