Получить текущее имя каталога (без полного пути) в скрипте Bash

Как бы получить текущее имя рабочего каталога в скрипте bash или, что еще лучше, просто команду терминала.

pwd дает полный путь к текущему рабочему каталогу, например /opt/local/bin но я хочу только bin

26 ответов

Решение

Нет необходимости в базовом имени, и особенно нет необходимости в подоболочке, выполняющей pwd (которая добавляет дополнительную и дорогостоящую операцию fork); оболочка может сделать это внутренне, используя расширение параметров:

result=${PWD##*/}          # to assign to a variable

printf '%s\n' "${PWD##*/}" # to print to stdout
                           # ...more robust than echo for unusual names
                           #    (consider a directory named -e or -n)

printf '%q\n' "${PWD##*/}" # to print to stdout, quoted for use as shell input
                           # ...useful to make hidden characters readable.

Обратите внимание, что если вы применяете эту технику в других обстоятельствах (не PWD, но некоторые другие переменные, содержащие имя каталога), возможно, вам придется обрезать любые косые черты. Ниже используется поддержка extglob в bash для работы даже с несколькими конечными слешами:

dirname=/path/to/somewhere//
shopt -s extglob           # enable +(...) glob syntax
result=${dirname%%+(/)}    # trim however many trailing slashes exist
result=${result##*/}       # remove everything before the last / that still remains
printf '%s\n' "$result"

Альтернативно, без extglob:

dirname="/path/to/somewhere//"
result="${dirname%"${dirname##*[!/]}"}" # extglob-free multi-trailing-/ trim
result="${result##*/}"                  # remove everything before the last /

Использовать basename программа. Для вашего случая:

% basename "$PWD"
bin
$ echo "${PWD##*/}"

Вы можете использовать комбинацию pwd и basename. Например

#!/bin/bash

CURRENT=`pwd`
BASENAME=`basename "$CURRENT"`

echo "$BASENAME"

exit;
basename "$PWD"

ИЛИ ЖЕ

IFS=/ 
var=($PWD)
echo ${var[-1]} 

Переведите внутренний разделитель имен файлов (IFS) обратно в пробел.

IFS= 

После IFS есть один пробел.

Как насчет grep:

pwd | grep -o '[^/]*$'
basename $(pwd)

или же

echo "$(basename $(pwd))"

Эта тема отличная! Вот еще один аромат:

pwd | awk -F / '{print $NF}'

Мне нравится выбранный ответ (Чарльз Даффи), но будьте осторожны, если вы находитесь в директории с символическими ссылками и хотите указать имя целевой директории. К сожалению, я не думаю, что это можно сделать в выражении расширения с одним параметром, возможно, я ошибаюсь. Это должно работать:

target_PWD=$(readlink -f .)
echo ${target_PWD##*/}

Чтобы увидеть это, эксперимент:

cd foo
ln -s . bar
echo ${PWD##*/}

сообщает "бар"

DIRNAME

Чтобы показать ведущие каталоги пути (без использования fork-exec /usr/bin/dirname):

echo ${target_PWD%/*}

Это, например, преобразует foo/bar/baz -> foo/bar

Очень просто

pwd | xargs basename
echo "$PWD" | sed 's!.*/!!'

Если вы используете оболочку Bourne или ${PWD##*/} не доступен.

Удивительно, но никто не упомянул об этой альтернативе, которая использует только встроенные команды bash:

i="$IFS";IFS='/';set -f;p=($PWD);set +f;IFS="$i";echo "${p[-1]}"

В качестве дополнительного бонуса вы можете легко получить имя родительского каталога с помощью:

[ "${#p[@]}" -gt 1 ] && echo "${p[-2]}"

Они будут работать на Bash 4.3-alpha или новее.

Просто запустите следующую командную строку:

      basename $(pwd)

Если вы хотите скопировать это имя:

      basename $(pwd) | xclip -selection clipboard

Есть целые много способов сделать это мне особенно понравился Чарльз путь, потому что избежать нового процесса, но прежде, чем знать это, я решил его с AWK

pwd | awk -F/ '{print $NF}'

Для поиска жокеев, как я:

find $PWD -maxdepth 0 -printf "%f\n"

Я обычно использую это в скриптах sh

SCRIPTSRC=`readlink -f "$0" || echo "$0"`
RUN_PATH=`dirname "${SCRIPTSRC}" || echo .`
echo "Running from ${RUN_PATH}"
...
cd ${RUN_PATH}/subfolder

Вы можете использовать это для автоматизации вещей...

Ниже grep с регулярным выражением также работает,

>pwd | grep -o "\w*-*$"

Если вы хотите видеть только текущий каталог в области приглашения bash, вы можете отредактировать .bashrc файл в ~. + Изменить\w к \W в соответствии:

PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '

Пробег source ~/.bashrc и он будет отображать только имя каталога в области подсказки.

Ссылка: https://superuser.com/questions/60555/show-only-current-directory-name-not-full-path-on-bash-prompt

Просто используйте:

pwd | xargs basename

или же

basename "`pwd`"

Я настоятельно предпочитаю использовать gbasename, который является частью GNU coreutils.

Вот простой псевдоним для него:

псевдоним name='базовое имя $( pwd )'

Поместив это в свой~/.zshrcили~/.bashrcфайл и найти его (например:source ~/.zshrc), то вы можете просто запуститьnameчтобы распечатать имя текущего каталога.

АльтернативаbasnameПримеры

      pwd | grep -o "[^/]*$"

ИЛИ

      pwd | ack -o "[^/]+$"

Моя оболочка не пришла сbasenamepackage, и я стараюсь избегать загрузки пакетов, если есть способы обойти это.

Вы можете использовать утилиту basename, которая удаляет любой префикс, заканчивающийся на / и суффикс (если присутствует в строке) из строки, и печатает результат на стандартном выводе.

$basename <path-of-directory>

Следующие команды приведут к печати вашего текущего рабочего каталога в bash-скрипте.

pushd .
CURRENT_DIR="`cd $1; pwd`"
popd
echo $CURRENT_DIR

Просто удалите любой символ, пока не появится (или \, если у вас Windows). Поскольку матч будет жадным, он удалит все до последнего /:

      pwd | sed 's/.*\///g'

В вашем случае результат ожидаемый:

      λ a='/opt/local/bin'

λ echo $a | sed 's/.*\///g'
bin

Я использую эту команду:

dirname "$0"

Другие вопросы по тегам