Was ist der einfachste Weg, um einen abschließenden Schrägstrich aus jedem Parameter zu entfernen?


90

Was ist der einfachste Weg, um einen abschließenden Schrägstrich aus jedem Parameter im Array '$ @' zu entfernen, damit rsyncdie Verzeichnisse nach Namen kopiert werden?

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

Der Titel wurde zur Verdeutlichung geändert. Informationen zu den Kommentaren und Antworten zu mehreren nachgestellten Schrägstrichen finden Sie im Bearbeitungsverlauf.


Antworten:


152

Sie können die Verwendung ${parameter%word}Expansion , die detailliert ist hier . Hier ist ein einfaches Testskript, das das Verhalten demonstriert:

#!/bin/bash

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

echo ${@%/}

34
+1: Um sehr pedantisch zu sein, wird ein einzelner Schrägstrich entfernt, nicht alle nachgestellten Schrägstriche. So entfernen Sie eine beliebige Anzahl von nachgestellten Schrägstrichen:shopt -s extglob; echo "${@%%+(/)}"
— Glenn Jackman

24
Warnung: Möglicherweise möchten Sie nachfolgende Schrägstriche nicht in allen Fällen entfernen. Wenn "/" als Argument angegeben wird, hat das Entfernen des abschließenden Schrägstrichs ... unglückliche Konsequenzen.
— Gordon Davisson

13
PROTIP: Kombinieren Sie tr -s /mit variablem regulären Ausdruck , um wiederholte Schrägstriche zu entfernen, und entfernen Sie dann den nachfolgenden Schrägstrich. zBDIR=$(echo //some///badly/written///dir////// | tr -s /); DIR=${DIR%/}
— Dave

1
"Ja wirklich?" Laufen set -- one///// two// three four/; shopt -s extglob; echo "${@%%+(/)}"Sie an einer Bash-Eingabeaufforderung und sagen Sie mir, was Sie sehen
— Glenn Jackman

1
@twalberg Ich schätze "Protips", die nicht nur alternative Antworten auf die Frage von OP in Kommentarthreads sind.
— Kyle Strand

36

Die akzeptierte Antwort schneidet EINEN abschließenden Schrägstrich ab.

Eine Möglichkeit, mehrere nachgestellte Schrägstriche zu kürzen, ist folgende:

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

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

echo $VALUE $TRIMMED

Welche Ausgänge:

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

1
Vergessen Sie nicht, Ihre Variablen zu zitieren, falls sie Leerzeichen enthalten: TRIMMED=$(echo "$VALUE" | sed 's:/*$::')
— Tetsujin

1
Eigentlich ist das im $()Konstrukt nicht nötig . Es ist jedoch auch harmlos :) Daher ist es wahrscheinlich eine gute Praxis, doppelte Anführungszeichen zu verwenden, "$VALUE"damit Sie nicht entscheiden müssen, wann und wann Sie die doppelten Anführungszeichen nicht verwenden möchten.
— Chris Johnson

Gibt es eine Möglichkeit, dies mit einer früheren Erfassung zu kombinieren? Ich möchte das Protokoll und (falls vorhanden) den abschließenden Schrägstrich von einer URL entfernen, echo "https://www.example.com/foo/" | sed -e 's|https*://\(.*\)/*$|\1|'funktioniert aber nicht (da die Erfassungsgruppe auch mit dem abschließenden Schrägstrich übereinstimmt, denke ich). Ich kann es mit zwei Befehlen machen: echo "https://www.example.com/foo/" | sed -e 's|https*://\(.*\)$|\1|' -e 's|/*$||'aber ich habe mich gefragt, ob es mit einem gemacht werden kann?
— Adam

Diese Antwort funktionierte bei mir mit einer sehr großen Eingabedatei besser. Ein einfacher sed 's:/*$::' < in.txt > out.txterledigt den Job in Sekunden
— MitchellK

19

Das funktioniert bei mir: ${VAR%%+(/)}

Wie hier beschrieben http://wiki.bash-hackers.org/syntax/pattern

Möglicherweise muss die Shell-Option extglob festgelegt werden. Ich kann nicht sehen, dass es für mich aktiviert ist, aber es funktioniert immer noch


2
So shopt extglob
— fragen Sie

Dies ist Extended Pattern Language und Sie müssen festlegen extglob.
— Ingyhere

1
Dies funktioniert nicht unter Mac OS Xs integriertem Bash. Die Lösung von Sean Bright oben lautet:${VAR%/}
— Alec Jacobson

11

realpathlöst den angegebenen Pfad auf. Unter anderem werden auch nachgestellte Schrägstriche entfernt. Verwenden Sie -sdiese Option, um folgende Simlinks zu vermeiden

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

1
Es erfordert alle Knoten im Pfad mit Ausnahme des letzten. Wenn der Benutzer einen nicht existierenden Pfad eingibt, schlägt dies realpathfehl.
— Livy

1
@Livy realpath --canonicalize-missingfunktioniert absolut korrekt mit jedem nicht vorhandenen Teil des Pfades
— maoizm

7

Zu Ihrer Information, ich habe diese beiden Funktionen .bash_profilebasierend auf den Antworten auf SO zu meinen hinzugefügt . Wie Chris Johnson sagte, ${x%/}entfernen alle Antworten, bei denen nur ein Schrägstrich verwendet wird, das, was sie sagen, und hoffen, dass dies nützlich ist.

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

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

4

In zsh können Sie den :aModifikator verwenden.

export DIRECTORY='/some//path/name//'

echo "${DIRECTORY:a}"

=> /some/path/name

Dies realpathverhält sich wie , fehlt jedoch nicht mit fehlenden Dateien / Verzeichnissen als Argument.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.