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.