В 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