jak usunąć ostatni ukośnik ścieżki katalogu?

17

Mam skrypt, który wymaga katalogu jako jednego argumentu. Chcę wesprzeć dwie formy: jedna jest jak

a/b/c

(bez slash na końcu), a inny jest jak

 a/b/c/

(ma slash na końcu).

Moje pytanie: biorąc pod uwagę którąkolwiek z dwóch form, jak mogę po prostu zachować pierwszą formę bez zmian i usunąć ostatni ukośnik z drugiej formy, aby przekonwertować ją na pierwszą formę.

Yulong Ao
źródło
2
Nie powinno to stanowić większego problemu - podwójny ukośnik w dowolnym miejscu, z wyjątkiem początku, jest równoważny pojedynczemu ukośnikowi, więc nie martw się o dołączenie do niego /.
mur
@muru Nie wiedziałem tego wcześniej :).
Yulong Ao
Oto dobre
pytanie
1
@muru Ukośnik na końcu może mieć znaczenie, na przykład różnica między działaniem na dowiązaniu symbolicznym a działaniem na katalog, na który wskazuje, lub argument źródłowy rsync.
Gilles 'SO - przestań być zły'
@Gilles rzeczywiście, ale jak widać, mówię o łączeniu ścieżek.
mur 24.04.2015

Odpowiedzi:

23
dir=${1%/}

weźmie pierwszy parametr skryptu i usunie ukośnik, jeśli taki istnieje.

Glenn Jackman
źródło
12

Aby usunąć końcowy ukośnik, jeśli taki istnieje, możesz użyć konstrukcji rozszerzającej parametru usuwania sufiksu obecnej we wszystkich powłokach w stylu POSIX:

x=${x%/}

Jest kilka komplikacji. Usuwa to tylko jeden ukośnik, więc jeśli zaczniesz od niego a/b/c//, nadal będziesz mieć ukośnik. Ponadto, jeśli oryginalna ścieżka była /, musisz zachować ukośnik. Oto bardziej złożone rozwiązanie, które zajmuje się tymi przypadkami:

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

Alternatywnie, w ksh lub w bash po shopt -s extglob:

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

Zauważ, że w wielu przypadkach nie ma znaczenia, że ​​występuje ukośnik końcowy. Nie ma znaczenia, czy argument jest dowiązaniem symbolicznym do katalogu: z ukośnikiem końcowym argument określa katalog, podczas gdy bez ukośnika, argument sam symbolicznie. Ma to również znaczenie w przypadku kilku innych programów, na przykład argument źródłowy rsyncjest traktowany inaczej w zależności od obecności końcowego ukośnika.

Gilles „SO- przestań być zły”
źródło
2

realpathrozwiązuje podaną ścieżkę. Między innymi usuwa również końcowe ukośniki. Służy -sdo zapobiegania poniższym linkom prostym

DIR=/tmp/a///
echo $(realpath -s $DIR)
# output: /tmp/a
czerny
źródło