Jaki jest najprostszy sposób na usunięcie końcowego ukośnika z każdego parametru w tablicy „$ @”, aby rsync
skopiować katalogi według nazwy?
rsync -a --exclude='*~' "$@" "$dir"
Tytuł został zmieniony w celu wyjaśnienia. Aby zrozumieć komentarze i odpowiedzieć na temat wielu końcowych ukośników, zobacz historię edycji.
Odpowiedzi:
Możesz skorzystać z
${parameter%word}
rozszerzenia opisanego tutaj . Oto prosty skrypt testowy, który demonstruje zachowanie:#!/bin/bash # Call this as: # ./test.sh one/ two/ three/ # # Output: # one two three echo ${@%/}
źródło
shopt -s extglob; echo "${@%%+(/)}"
tr -s /
ze zmiennym wyrażeniem regularnym, aby usunąć powtarzające się ukośniki, a następnie usuń ukośnik końcowy. np.DIR=$(echo //some///badly/written///dir////// | tr -s /); DIR=${DIR%/}
set -- one///// two// three four/; shopt -s extglob; echo "${@%%+(/)}"
i powiedz mi, co widziszZaakceptowana odpowiedź spowoduje przycięcie JEDNEGO końcowego ukośnika.
Jeden ze sposobów przycinania wielu końcowych ukośników jest taki:
VALUE=/looks/like/a/path/// TRIMMED=$(echo $VALUE | sed 's:/*$::') echo $VALUE $TRIMMED
Które wyjścia:
źródło
TRIMMED=$(echo "$VALUE" | sed 's:/*$::')
$()
konstrukcji. Jednak jest to również nieszkodliwe :), więc prawdopodobnie dobrym zwyczajem jest używanie podwójnych cudzysłowów,"$VALUE"
aby nie musieć decydować, kiedy i kiedy nie używać cudzysłowów.echo "https://www.example.com/foo/" | sed -e 's|https*://\(.*\)/*$|\1|'
nie działa (ponieważ grupa przechwytywania pasuje również do końcowego ukośnika). Mogę to zrobić za pomocą dwóch poleceń:echo "https://www.example.com/foo/" | sed -e 's|https*://\(.*\)$|\1|' -e 's|/*$||'
ale zastanawiałem się, czy można to zrobić jednym?sed 's:/*$::' < in.txt > out.txt
działa w kilka sekundTo działa dla mnie:
${VAR%%+(/)}
Jak opisano tutaj http://wiki.bash-hackers.org/syntax/pattern
Może być konieczne ustawienie opcji powłoki extglob. Nie widzę tego włączonego, ale nadal działa
źródło
shopt extglob
bez opcjiextglob
.${VAR%/}
realpath
rozwiązuje podaną ścieżkę. Między innymi usuwa również końcowe ukośniki. Użyj,-s
aby zapobiec następowaniu linków SIMDIR=/tmp/a/// echo $(realpath -s $DIR) # output: /tmp/a
źródło
realpath
zakończy się niepowodzeniem.realpath --canonicalize-missing
działa absolutnie poprawnie z każdą nieistniejącą częścią ścieżkiFYI, dodałem te dwie funkcje do mojej
.bash_profile
na podstawie odpowiedzi znalezionych w SO. Jak powiedział Chris Johnson, wszystkie odpowiedzi za pomocą${x%/}
usuwają tylko jeden ukośnik, te funkcje zrobią to, co mówią, mam nadzieję, że będzie to przydatne.rem_trailing_slash() { echo "$1" | sed 's/\/*$//g' } force_trailing_slash() { echo "$(rem_trailing_slash "$1")/" }
źródło
W zsh możesz użyć
:a
modyfikatora.export DIRECTORY='/some//path/name//' echo "${DIRECTORY:a}" => /some/path/name
Działa to tak, jak,
realpath
ale nie kończy się niepowodzeniem w przypadku braku plików / katalogów jako argumentu.źródło