Як отримати останню частину ім’я в Bash


81

Припустимо, у мене є файл /from/here/to/there.txt, і я хочу отримати лише останню частину його імені toзамість того /from/here/to, що мені робити?

Відповіді:


120

Ви можете використовувати, basenameнавіть якщо це не файл. Видаліть ім'я файлу за допомогою dirname, а потім використовуйте, basenameщоб отримати останній елемент рядка:

dir="/from/here/to/there.txt"
dir="$(dirname $dir)"   # Returns "/from/here/to"
dir="$(basename $dir)"  # Returns just "to"

2
команда '$ dir = "$ (dirname $ dir)"' у мене не працює, але 'dir = "$ (dirname $ dir)"' працює нормально.
Микола Сайко

2
Я не повинен був мати долар перед тим, dirяк я встановлюю це.
Девід В.



9

За допомогою розширення параметрів Bash ви можете зробити це:

path="/from/here/to/there.txt"
dir="${path%/*}"       # sets dir      to '/from/here/to' (equivalent of dirname)
last_dir="${dir##*/}"  # sets last_dir to 'to' (equivalent of basename)

Це більш ефективно, оскільки зовнішні команди не використовуються.


Я щойно перевірив це. На FreeBSD ось мої результати: Код: #! / Bin / sh cd / var / svn / repos path = "$ 1" echo "$ {path}" dir = "$ {path% / *}" echo "$ {dir } "фактично =" $ {dir ## * /} "echo" $ {actual} "----------------------------- ----------- Результати: $ ./makerepo.sh / var / test / var / test / var var $ ------------------- ----------------- Помилка! Вибачте. Здавалося, хороший метод, але не правильна відповідь.
Річард Робертсон,

4

Чистий BASH спосіб:

s="/from/here/to/there.txt"
[[ "$s" =~ ([^/]+)/[^/]+$ ]] && echo "${BASH_REMATCH[1]}"
to

2
Не буде працювати, якщо у файлі немає крапки .. Не буде працювати, якщо каталог містить крапку .. Будьте простішими та використовуйте скісну риску /як роздільник.
приймає рішення

1
Велике спасибі @Akshay
anubhava

3

awkСпосіб зробити це буде:

awk -F'/' '{print $(NF-1)}' <<< "/from/here/to/there.txt"

Пояснення:

  • -F'/' встановлює роздільник поля як "/"
  • надрукувати друге останнє поле $(NF-1)
  • <<<використовує що-небудь після цього як стандартне введення ( пояснення wiki )


1

Це питання що - щось на зразок цього .

Для вирішення, яке ви можете зробити:

DirPath="/from/here/to/there.txt"
DirPath="$(dirname $DirPath)"
DirPath="$(basename $DirPath)"

echo "$DirPath"

Як сказав мій друг, це можливо також:

basename `dirname "/from/here/to/there.txt"`

Щоб отримати будь-яку частину свого шляху, ви можете зробити:

echo "/from/here/to/there.txt" | awk -F/ '{ print $2 }'
OR
echo "/from/here/to/there.txt" | awk -F/ '{ print $3 }'
OR
etc

1

Верхня відповідь абсолютно правильна для поставленого питання. У більш загальному випадку, коли необхідний каталог знаходиться посередині довгого шляху, такий підхід призводить до важкого для читання коду. Наприклад :

dir="/very/long/path/where/THIS/needs/to/be/extracted/text.txt"
dir="$(dirname $dir)"
dir="$(dirname $dir)"
dir="$(dirname $dir)"
dir="$(dirname $dir)"
dir="$(dirname $dir)"
dir="$(basename $dir)"

У цьому випадку можна використовувати:

IFS=/; set -- "/very/long/path/where/THIS/needs/to/be/extracted/text.txt"; set $1; echo $6
THIS
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.