як зняти останню косу риску шляху до каталогу?


17

У мене є сценарій, для якого потрібен каталог як один аргумент. Я хочу підтримати дві форми: одна схожа

a/b/c

(жодної косою рисою в кінці) та інша схожа

 a/b/c/

(має косу рису в кінці).

Моє запитання: з огляду на будь-яку з двох форм, як я можу просто зберегти першу форму без змін та зняти останню косу рису другої форми, щоб перетворити її в першу форму.


2
Не те, що це має бути великою проблемою - подвійний косий кут в будь-якому місці, окрім початку, еквівалентний одному косому рису, тому не переживайте за приєднання до них /.
муру

@muru Я цього раніше не знав :).
Юлонг Ао


1
@muru Штрих у кінці може змінити значення, наприклад, різницю між дією на симпосилання та дією на каталог, на який вказує, або аргументом джерела rsync.
Жил "ТАК - перестань бути злим"

@Gilles дійсно, але, як бачите, я кажу про приєднання шляхів.
муру

Відповіді:



12

Для видалення косої риски, якщо вона є, ви можете використовувати конструкцію розширення параметра видалення суфіксу, яка присутня у всіх оболонках стилю POSIX:

x=${x%/}

Є кілька ускладнень. Це видаляє лише одну косу рису, тож якщо ви почали з неї, a/b/c//ви все одно закінчите косу рису. Крім того, якщо оригінальний шлях був /, потрібно зберегти косу рису. Ось більш складне рішення, яке стосується цих випадків:

case $x in
  *[!/]*/) x=${x%"${x##*[!/]}"};;
  *[/]) x="/";;
esac

Крім того, в ksh або bash після shopt -s extglob:

[[ x = *[!/] ]] || x=${x%%*(/)}

Зауважте, що у багатьох випадках не має значення, що є кінець косої риски. Немає значення, якщо аргумент є символічним посиланням на каталог: з косою косою рисою аргумент позначає каталог, тоді як при відсутності косої косої риски аргумент позначає саме символічне посилання. Це також має значення з кількома іншими програмами, наприклад, аргументом джерелаrsync трактується по-різному в залежності від наявності останньої косої риски.


2

realpathвирішує заданий шлях. Крім усього іншого, він також видаляє задні косої риски. Використовуйте -sдля запобігання наступних посилань

DIR=/tmp/a///
echo $(realpath -s $DIR)
# output: /tmp/a
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.