169 votes

Quel est le moyen le plus simple de supprimer la barre oblique de fin de chaque paramètre ?

Quel est le moyen le plus simple de supprimer la barre oblique de fin de chaque paramètre du tableau "$@", de sorte que rsync copie les répertoires par leur nom ?

rsync -a --exclude='*~' "$@" "$dir"

Le titre a été modifié pour plus de clarté. Pour comprendre les commentaires et la réponse concernant les barres obliques multiples, consultez l'historique des modifications.

2 votes

267voto

Sean Bright Points 39480

Vous pouvez utiliser le ${parameter%word} une expansion qui est détaillée aquí . Voici un simple test script qui démontre ce comportement :

#!/bin/bash

# Call this as:
#   ./test.sh one/ two/ three/ 
#
# Output:
#  one two three

echo ${@%/}

52 votes

+1 : Pour être très pédant, cela supprimera une seule barre oblique, pas toutes les barres obliques de fin. Pour supprimer n'importe quel nombre de barres obliques de fin : shopt -s extglob; echo "${@%%+(/)}"

32 votes

Attention : vous ne voudrez peut-être pas supprimer les slashs de fin dans tous les cas. Si "/" est fourni comme argument, la suppression de la barre oblique de fin aura des conséquences ... malheureuses.

16 votes

PROTIP : Combinez tr -s / avec une expression rationnelle variable pour supprimer les barres obliques répétées, puis supprimer la barre oblique de fin. DIR=$(echo //some///badly/written///dir////// | tr -s /); DIR=${DIR%/}

65voto

Chris Johnson Points 2887

La réponse acceptée coupera UN slash de fin.

Voici une façon de couper plusieurs barres obliques de fin de ligne :

VALUE=/looks/like/a/path///

TRIMMED=$(echo $VALUE | sed 's:/*$::')

echo $VALUE $TRIMMED

Quelles sorties :

/looks/like/a/path/// /looks/like/a/path

1 votes

N'oubliez pas de citer vos variables, au cas où elles contiendraient des espaces : TRIMMED=$(echo "$VALUE" | sed 's:/*$::')

3 votes

En fait, ce n'est pas nécessaire à l'intérieur de la $() construire. Cependant, c'est aussi inoffensif :) donc c'est probablement une bonne pratique d'utiliser les guillemets doubles comme "$VALUE" afin que vous n'ayez pas à décider quand utiliser ou non les guillemets.

0 votes

Y a-t-il un moyen de combiner ceci avec une capture antérieure ? Je veux supprimer le protocole et (s'il est présent) le slash de fin d'URL, mais echo "https://www.example.com/foo/" | sed -e 's|https*://\(.*\)/*$|\1|' ne fonctionne pas (puisque le groupe de capture correspond également à la barre oblique de fin, je suppose). Je peux le faire avec deux commandes : echo "https://www.example.com/foo/" | sed -e 's|https*://\(.*\)$|\1|' -e 's|/*$||' mais je me demandais si on pouvait le faire avec un seul ?

40voto

Ivan Points 251

Cela fonctionne pour moi : ${VAR%%+(/)}

Comme décrit ici http://wiki.bash-hackers.org/syntax/pattern

Vous devrez peut-être activer l'option extglob du shell. Je ne la vois pas activée pour moi, mais elle fonctionne toujours.

3 votes

Pour interroger un paramètre : shopt extglob sans options

4 votes

C'est un langage de modèle étendu et vous doit set extglob .

2 votes

Cela ne fonctionne pas avec le bash intégré de Mac OS X. La solution de Sean Bright ci-dessus fonctionne : ${VAR%/}

40voto

czerny Points 51

realpath résout le chemin donné. Entre autres choses, il supprime également les slashs de fin de ligne. Utiliser -s pour empêcher les simlinks suivants

DIR=/tmp/a///
echo $(realpath -s $DIR)
# output: /tmp/a

3 votes

Il faut que tous les nœuds du chemin, à l'exception du dernier, existent. Si l'utilisateur ajoute un chemin inexistant, realpath doit échouer.

4 votes

@Livy realpath --canonicalize-missing fonctionne absolument correctement avec n'importe quelle partie inexistante du chemin d'accès

0 votes

Et realpath est absent sur certaines plateformes :-(

11voto

Sh3ljohn Points 746

Pour info, j'ai ajouté ces deux fonctions à mon fichier .bash_profile sur la base des réponses trouvées sur SO. Comme Chris Johnson l'a dit, toutes les réponses utilisant ${x%/} supprimer un seul slash, ces fonctions feront ce qu'elles disent, j'espère que cela vous sera utile.

rem_trailing_slash() {
    echo "$1" | sed 's/\/*$//g'
}

force_trailing_slash() {
    echo "$(rem_trailing_slash "$1")/"
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X