in einem Script, bei Pfadangaben hinten Slashes entfernen

Post Reply
Message
Author
micbur
Posts: 86
Joined: 05. Jun 2004 15:55

in einem Script, bei Pfadangaben hinten Slashes entfernen

#1 Post by micbur »

Hallo,

ich habe mir ein Script geschrieben, in dem ein rsync-Aufruf ist. Es gibt auch einen Parameter für das Script. Nun reichen meine Fähigkeiten nicht aus und so recht weiß ich auch nicht, wonach ich eigentlich suche. Ich möchte beim Parameter hinten die Slashes entfernen. Der Parameter stellt einen Teil eines Pfades dar und die Slashes stören dabei.

Aufgerufen wird mein Shell-Script, von einem PHP-Script. Im Normalfall sollten dort schon eventuelle Backslasches durch Slashes ersetzt und die hinteren Slashes entfernt sein. Man kann ja aber auch mein Shell-Script auch von der Kommandozeile aufrufen und daher brauche ich da einfach noch eine Prüfung.

Kann mir da jemand zumindest sagen, was ich eigentlich suche?
Oder geht das gar nicht, was ich will?


Danke & Ciao, micbur

User avatar
jochen
prolinux-forum-admin
Posts: 699
Joined: 14. Jan 2000 15:37
Location: Jülich
Contact:

#2 Post by jochen »

Slashes am Ende eines Arguments entfernen ist einfach.

... war mein erster Ansatz für dieses Posting. Ich bin immer noch der Meinung, dass es doch eine einfachere Lösung geben müsste, aber die einzige, auf die ich gerade komme, ist diese hier:

Code: Select all

#!/bin/bash

function chop_slashes {
        typeset I
        typeset J

        J="$1"
        I="${J%/}"
        until [[ "x$I" = "x$J" ]] ; do
                J="$I"
                I="${J%/}"
        done
        echo $J
}
Zu verwenden ist die Funktion wie folgt:

Code: Select all

ARG=$(chop_slashes "$1")
Eventuell existierende Slashes am Ende werden abgetrennt, andere Zeichenketten (ohne Slashes am Ende) werden unverändert ausgegeben.

Nun gut, man könnte natürlich auch

Code: Select all

VAR=$(echo "$ARG" | sed -e 's-/*$--')
schreiben, aber dann hat man pro Argument, dass man beharken möchte, einen sed-Aufruf. Die erste Lösung ist da eher schneller.

Jochen
Die grösste Lüge der EDV? "Mal eben..."

micbur
Posts: 86
Joined: 05. Jun 2004 15:55

#3 Post by micbur »

Hallo,

danke für den guten Hinweis.
Ich habe im Internet ein Beispiel gefunden, wo es auch um das Abschneiden von Strings geht. Ich experimentiere dadurch gerade mit einer Kombination aus echo und cut herum.

Beispiel

Code: Select all

echo test | cut -c -3
hat die Ausgabe

Code: Select all

tes
Ciao, micbur

User avatar
jochen
prolinux-forum-admin
Posts: 699
Joined: 14. Jan 2000 15:37
Location: Jülich
Contact:

#4 Post by jochen »

Ja, aber dann musst Du erst mal die Länge des Strings feststellen. Und was passiert, wenn mal mehr als nur ein / zuviel am Pfad hängt? Da Du dann mehrfach externe Programme aufrufen musst, kannst Du dann auch direkt die sed-Lösung verwenden - ein Prozess pro Pfad und Ende. Oder aber nur bash-Hilfsmittel verwenden und die erste Lösung ohne Aufruf externer Programme verwenden.

Jochen
Die grösste Lüge der EDV? "Mal eben..."

micbur
Posts: 86
Joined: 05. Jun 2004 15:55

#5 Post by micbur »

OKOK, hmmm, also ich habe nun auch mal komplett deine Lösung ausprobiert. Nur leider kann ich nicht sehen wie sie funktioniert. Ich versuche dahinterzusteigen.

Aber schonmal vielen Dank und ein frohes Fest, micbur

User avatar
jochen
prolinux-forum-admin
Posts: 699
Joined: 14. Jan 2000 15:37
Location: Jülich
Contact:

#6 Post by jochen »

Dann wollnwer mal... :)

Code: Select all

typeset I
typeset J 
definiert die Variablen I und J als funktionslokal, damit keine Nebeneffekte auftreten, wenn Du auch in deinem Skript irgendwo I und J als Variablennamen verwenden solltest.

Code: Select all

J="$1"
I="${J%/}" 
J wird initialisiert mit dem ersten Argument der Funktion (also dem Pfad, der zu kürrzen ist). I wird als Inhalt von J initialisiert, aber wenn am Ende des Inhalt von J ein "/" steht, wird es entfernt. Siehe "man bash", Abschnitt "Parameter Expansion". Vor dem % steht der Variablenname, nach dem % das Pattern, das aus der Zeichenkette anm Ende gelöscht werden soll ("/" eben).

Code: Select all

until [[ "x$I" = "x$J" ]] ; do 
Diese Schleife läuft solange, bis I ind J gleich sind. Das ist dann der Fall, wenn an der Inhalt von J gar nicht auf "/" endet und bei der Zuweisung an I auch kein Zeichen entfernt wird. Der Schleifenkörper wird also nur ausgeführt, wenn bislang ein "/" entfernt werden konnte.

Code: Select all

    J="$I"
    I="${J%/}"
done 
J wird der um ein Zeichen verkürzte Pfad zugewiesen, I wieder der Inhalt von J weniger einem eventuellen Slash am Ende. Dann ist der Schleifenkörper zu Ende und am Schleifenkopf wird wieder geprüft, ob die zwei Variablen jetzt gleich sind.

Code: Select all

echo $J 
Wenn nichts mehr verkürzt wurde, wird die Schleife verlassen. Also das Ergebnis ausgeben.

Alles klar soweit oder sind noch Fragen offen?

Jochen
Die grösste Lüge der EDV? "Mal eben..."

micbur
Posts: 86
Joined: 05. Jun 2004 15:55

#7 Post by micbur »

Danke, danke, danke.

Alles klar. Habe das Script auch schon angepasst. Mir ist dann auch gleich aufgefallen, dass die Bash keine Scopes/Namespaces kennt. Daran muss man sich erstmal wieder gewöhnen, wenn man lange OO programmiert hat. ;-)

Aber ansonsten hat mir das und das hier weitergeholfen.

Ciao, micbur



PS:
Aus deinem Script ist jetzt Folgenes geworden:

Code: Select all

# hier wird ein Verzeichnisname zurechtgestutzt.
# Nehmen wir an, eine Eingabe war mangelhaft, indem zu viele Slashes am Ende des Pfades
#  angegeben wurden. Fuer rsync sind diese Slashes zu viel fatal. Man synchronisiert dann
#  falsche Verzeichnisse miteinander. Meist so, dass das zu synchronisierene Verzeichnis
#  auf dem Zielsystem noch einmal in sich hinein synchronisiert wird.
#     Beispiel&#58; host1&#58;/path/to/sync              <- Quellensystem
#               host2&#58;/path/to/sync/sync         <- Zielsystem
    dirname="$1"                          # sichern des Parameters
    parentdir="$&#123;1%/&#125;"                    # parentdir ist der Parameter ohne dem letzten Slash &#40;so es ihn gibt&#41;
                                          # hier wird so geparst&#58; modifikation="$&#123;original%pattern&#125;
                                          #    dabei wird das Original um das Pattern gestutzt
                                          #    ist das Pattern nicht vorhanden, ist die Modifikation identisch mit dem Original
    until &#91;&#91; "x$parentdir" = "x$dirname" &#93;&#93; ; do
      # in dieser Schleife wird so lange der letzte Slash gestutzt, bis keiner mehr vorhanden ist
      dirname="$parentdir"
      parentdir="$&#123;dirname%/&#125;"
    done
    # hier haben wir in den Variablen 'dirname' und 'parentdir' denselben Pfad ohne die letzten Slashes
    parentdir="$&#123;parentdir%/*&#125;"           # fuer das Parentdir wird nochmal von hinten alles bis zum nächten Slash abgeschnitten
                                          # Pattern ist hier '/*'

#    echo "Verzeichnisname   &#58; $dirname"
#    echo "Parentverzeichnis &#58; $parentdir"
Oben im Script wird dann noch geprüft, ob es überhaupt ein $1 gibt.


Ciao, micbur

User avatar
frank rudolph
Posts: 146
Joined: 13. Apr 2004 12:18
Location: Giessen
Contact:

schön

#8 Post by frank rudolph »

Hallo
Es ist doch immer wieder schön kleine Scripte zu lesen die von Jochen kommentiert sind.

Ich habe zwar im Moment nicht genau das Problem mit den Slashes aber ich schaue mit immer mit Begeisterung die Skripte an und wenn sie dann auch noch so schön kommentiert und erklärt sind dann kann man (ich) eine Menge lernen.

Vielen Dank!!!! und einen guten rutsch ins neue Jahr
mfg
Frank

Post Reply