6

Как извлечь путь к директории из пути к файлу?

13

В Bash, у меня есть переменная VAR="/home/me/mydir/file.c", и мне нужно извлечь из неё путь "/home/me/mydir". Как это можно сделать?

5 ответ(ов)

1

Вы можете использовать параметры подстановки в оболочке Bash для извлечения компонентов пути файла без необходимости использования дополнительных утилит, таких как basename и dirname.

В приведенном вами примере:

  1. Вы задаете переменную VAR со значением /home/me/mydir/file.c.

  2. Затем с помощью ${VAR%/*} вы извлекаете директорию, которая находится до последнего слэш-символа в пути. В результате этой операции вы получите /home/me/mydir, и это значение присваивается переменной DIR.

  3. Для извлечения имени файла, которое является частью пути, вы используете ${VAR##*/}. Это выражение удаляет все символы до последнего слэша (включительно), оставляя только имя файла, то есть file.c.

Таким образом, вы получаете рабочий способ извлечения директории и имени файла, не полагаясь на утилиты basename и dirname, только с помощью встроенных возможностей оболочки Bash.

0

Если у вас есть только имя файла или относительный путь, то dirname сам по себе не поможет решить задачу. В моем случае ответом стал readlink.

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

Вы можете объединить оба этих вызова, чтобы получить только директорию:

echo $(dirname $(readlink -f "$fname")) # вывод: /home/me/work
0

Если вам нужно обработать целевые файлы как символические ссылки, сначала вы можете проверить, является ли файл символической ссылкой, и получить оригинальный файл. В приведённом ниже условии if может быть полезно следующее:

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

Этот код сначала проверяет, является ли файл символической ссылкой с помощью -h. Если это так, он использует команду readlink для получения пути к оригинальному файлу и извлекает его директорию с помощью dirname. Если файл не является символической ссылкой, просто извлекается директория исходного файла.

0

Команда HERE=$(cd $(dirname $BASH_SOURCE) && pwd) используется для получения полного пути к каталогу, в котором находится скрипт.

Давайте разберем её по частям:

  1. $(dirname $BASH_SOURCE) — эта часть получает путь к каталогу, где расположен текущий исполняемый скрипт. Переменная $BASH_SOURCE содержит путь к скрипту, и команда dirname извлекает из него директорию.

  2. cd $(dirname $BASH_SOURCE) — здесь мы переходим в полученный каталог. Это позволяет нам изменить рабочую директорию на ту, где находится скрипт.

  3. pwd — эта команда выводит текущий рабочий каталог в терминале.

Таким образом, вся команда HERE=$(cd $(dirname $BASH_SOURCE) && pwd) сначала перемещает нас в директорию скрипта, а затем сохраняет полный путь к этой директории в переменную HERE.

При этом, такая конструкция позволяет избежать ошибок, связанных с относительными путями, что полезно при работе со скриптами, которые могут быть запущены из разных мест.

0

Вы можете использовать команду dirname для извлечения каталога из пути файла, и ваш подход с использованием xargs тоже работает. Вот пример, который я нашел:

$ 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

Этот код успешно извлекает нужный путь, поднимаясь вверх по дереву каталогов. Однако можно упростить код, используя dirname несколько раз в одном выражении, без использования xargs. Например:

$ DIR=$(dirname $(dirname $(dirname $VAR)))
$ echo $DIR
/home

Такой подход делает код более читаемым и понятным.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь