Как получить корневой каталог по заданному пути в bash?

Мой сценарий:

    #!/usr/bin/env bash
    PATH=/home/user/example/foo/bar
    mkdir -p /tmp/backup$PATH

И теперь я хочу получить первую папку «$ PATH»: /home/

    cd /tmp/backup
    rm -rf ./home/
    cd - > /dev/null

Как я могу всегда обнаруживать первую папку, как в примере выше? "dirname $PATH" просто возвращает "/home/user/example/foo/".

Заранее спасибо! :)


person user2966991    schedule 08.07.2014    source источник


Ответы (7)


Я нашел решение:

    #/usr/bin/env bash
    DIRECTORY="/home/user/example/foo/bar"
    BASE_DIRECTORY=$(echo "$DIRECTORY" | cut -d "/" -f2)
    echo "#$BASE_DIRECTORY#";

Это всегда возвращает первый каталог. В этом примере он вернет следующее:

    #home#

Спасибо @condorwasabi за его идею с awk! :)

person user2966991    schedule 09.07.2014
comment
Если ваш путь относительный и выглядит следующим образом: dir1/in/dir2, вам следует настроить таргетинг на поле -f1 вместо -f2 - person dmeu; 05.04.2016

Если PATH всегда имеет абсолютную форму, вы можете делать такие трюки, как

ROOT=${PATH#/} ROOT=/${ROOT%%/*}

Or

IFS=/ read -ra T <<< "$PATH"
ROOT=/${T[1]}

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

Также вы можете преобразовать свой путь в абсолютную форму через readlink -f или readlink -m:

ABS=$(readlink -m "$PATH")

Вы также можете обратиться к моей функции scripts-3956/" rel="noreferrer">getabspath.

person konsolebox    schedule 08.07.2014
comment
Извините, но я этого не понимаю. о.О Но спасибо. - person user2966991; 09.07.2014
comment
Ну очень плохо. Удачи :) - person konsolebox; 09.07.2014

Вы можете попробовать эту команду awk:

 basedirectory=$(echo "$PATH" | awk -F "/" '{print $2}')

В этот момент basedirectory будет строкой home Затем вы пишете:

rm -rf ./"$basedirectory"/
person condorwasabi    schedule 08.07.2014
comment
Это выглядит хорошо, но это не работает. $basedirectory всегда пуст. Но спасибо! :) - person user2966991; 09.07.2014
comment
Рад, что вы нашли решение. В любом случае, вы были правы, я только что отредактировал сценарий. Я не знаю, почему я написал {print $1}, я также проверил это перед публикацией. Теперь это должно работать. - person condorwasabi; 10.07.2014

Чтобы получить первую огненную башню:

path=/home/user/example/foo/bar
mkdir -p "/tmp/backup$path"
cd /tmp/backup
arr=( */ )
echo "${arr[0]}"

PS: Никогда не используйте переменную PATH в своем скрипте, так как она переопределит PATH по умолчанию, и ваш скрипт не сможет выполнять многие системные утилиты

EDIT: Вероятно, это должно сработать для вас:

IFS=/ && set -- $path; echo "$2"
home
person anubhava    schedule 08.07.2014
comment
Я думаю, пользователь хочет извлечь из него home. - person anishsane; 08.07.2014
comment
Хм How can I always detect the first folder like the example above не очень понятно. Я интерпретировал это так, как будто OP пытается получить первый каталог из пути /tmp/backup. - person anubhava; 08.07.2014
comment
Я начал комментарий с намерением поблагодарить вас и +1 за ваше предупреждение о переменной PATH. :) Потом понял, что ответ, возможно, не удовлетворяет требованию ОП. - person anishsane; 08.07.2014
comment
Хм, вероятно, konsolebox правильно интерпретировал это в этом случае - person anubhava; 08.07.2014
comment
Из вопроса: And now I want to get first folder of "$PATH": /home/ - person anishsane; 08.07.2014
comment
Спасибо за помощь, но ваше решение немного сбивает с толку. Я нашел еще один. :) - person user2966991; 09.07.2014
comment
Какая часть вас смущает? - person anubhava; 09.07.2014
comment
обр=( /* ). echo просто возвращает первый индекс массива или? - person user2966991; 10.07.2014
comment
На самом деле это arr=( */ ), который заполняет массив arr всеми каталогами в текущем пути. - person anubhava; 10.07.2014

Чистый баш:

DIR="/home/user/example/foo/bar"
[[ "$DIR" =~ ^[/][^/]+ ]] && printf "$BASH_REMATCH"

Легко настроить регулярное выражение.

person Thom    schedule 05.08.2018

Вы можете использовать dirname...

#/usr/bin/env bash
DIRECTORY="/home/user/example/foo/bar"
BASE_DIRECTORY=$(dirname "${DIRECTORY}")
echo "#$BASE_DIRECTORY#";

Выводит следующее...

/home/user/example/foo
person RobLoach    schedule 18.05.2020
comment
Решение должно выводить home, а не /home/user/example/foo. - person shrewmouse; 27.05.2020

Чтобы получить первый компонент каталога VAR:

echo ${VAR%${VAR#/*/}}

Итак, если VAR="/path/to/foo", возвращается /path/.

Объяснение:

${VAR#X} удаляет префикс X и возвращает остаток. Итак, если VAR=/path/to/foo, то /*/ соответствует префиксу /path/, и выражение возвращает суффикс to/foo.

${VAR%X} удаляет суффикс X. Вставляя вывод ${VAR#X}, он удаляет суффикс и возвращает префикс.

Если вы можете гарантировать, что ваши пути правильно сформированы, это удобный метод. Это не сработает для некоторых путей, таких как //path/to/foo или path/to/foo, но вы можете справиться с такими случаями, разбивая строки дальше.

person Alcamtar    schedule 29.07.2021