как удалить последний слеш пути к каталогу?

17

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

a/b/c

(без косой черты в конце) и другой как

 a/b/c/

(косая черта в конце).

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

Юлонг Ао
источник
2
Не то чтобы это должно было быть большой проблемой - двойной слеш в любом месте, кроме как в начале, эквивалентен одиночному слешу, так что не беспокойтесь о присоединении к ним, используя /.
Муру
@muru Я не знал этого раньше :).
Юлонг Ао
1
@muru Косая черта в конце может иметь значение, например, разница между действием по символической ссылке и действием в каталоге, на который она указывает, или в качестве исходного аргумента rsync.
Жиль "ТАК - перестань быть злым"
@ Жиль действительно, но, как вы можете видеть, я имею в виду объединение путей.
Муру

Ответы:

23
dir=${1%/}

примет первый параметр скрипта и удалит косую черту, если он есть.

Гленн Джекман
источник
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
Черни
источник