PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : bash: string nach regexp gruppen zerlegen



schibbl
09-04-2008, 11:39
Hallo!

ich möchte gern einen String - welcher meinem shell script per switch übergeben wird - validieren und die werte der einzelnen regular expression groups in einzelne variablen speichern. Die Regexp habe ich bereits erstellt und ich kenne die Möglichkeit es in Java zu lösen, aber bash ist zwingend.

Aufruf:
$> test.sh -u usr/pwd@masch

Der String kann folgend aussehen:

usr
usr/pwd
usr/pwd@maschine


Meine regexp sieht so aus:
^\w{1,}(\/\w{1,}(@\w{1,})?)?$

es soll so verteilt werden, dass:
USR_NAME=usr
USR_PWD=pwd
USR_MAS=maschine

dann im script ist.

Ich habe es bereits mit sed probiert, was mir aber nur den gesamten String zurück gibt.
$> echo "usr/pwq@maschine" | sed -e 's/^\w{1,}(\/\w{1,}(@\w{1,})?)?$//'

Danke,
schibbl

ContainerDriver
09-04-2008, 12:40
Hallo,

bei mir braucht sed die Option -r, dann wird der String ersetzt. Zerschneiden könntest du den String ja dann mit cut.

Gruß, Florian

undefined
09-04-2008, 19:57
Warum so umständlich:confused:

echo "usr/pwq@maschine" | awk -F/ '{print $1}'

lilapause
11-04-2008, 02:30
Warum so umständlich:confused:

echo "usr/pwq@maschine" | awk -F/ '{print $1}'
Fast...

echo "usr/pwq@maschine" | awk -F'/|@' '{print $1}'

ContainerDriver
11-04-2008, 07:58
Damit wird der String aber nicht validiert.

WeenerChild
11-04-2008, 13:27
bei mir braucht sed die Option -r, dann wird der String ersetzt.
Afaik Schwachfug, bei gnu sed sollte das für "extended regular expressions" stehen. Inplace-Bearbeitung von Dateien kann man mit dem i-switch erreichen, "strings ersetzen" würde man wahrscheinlich am Besten mit dem "s" Kommando machen...
Btw: der Quantifier "+" ist eine Kurzform für "{1,}".

string='usr/pwd@maschine'
RE='^(\w+)((/\w+)(@\w+)?)?$'
if [[ "$string" =~ $RE ]]; then
USR_NAME="${BASH_REMATCH[1]}"
USR_PWD="${BASH_REMATCH[3]:1}"
USR_MAS="${BASH_REMATCH[4]:1}"
fi

Edit: Also das wäre jetzt mal eine "bash only" Lösung, mit awk, perl etc. kann man das sicherlich auch lösen.. (Und wahrscheinlich auch wesentlich portabler, aber der TE sagte ja "bash ist Vorgabe"...)

ContainerDriver
11-04-2008, 13:58
Afaik Schwachfug, bei gnu sed sollte das für "extended regular expressions" stehen. Inplace-Bearbeitung von Dateien kann man mit dem i-switch erreichen, "strings ersetzen" würde man wahrscheinlich am Besten mit dem "s" Kommando machen...


Ich weiß nicht, ob du mein Posting falsch verstanden hast, aber mit der Option "-r" geht bei mir die Ersetzung.



florian@leuchtturm0:~$ echo "usr/pwq@maschine" | sed -e 's/^\w{1,}(\/\w{1,}(@\w{1,})?)?$//'
usr/pwq@maschine
florian@leuchtturm0:~$ echo "usr/pwq@maschine" | sed -r -e 's/^\w{1,}(\/\w{1,}(@\w{1,})?)?$//'

florian@leuchtturm0:~$

WeenerChild
11-04-2008, 15:53
Ich weiß nicht, ob du mein Posting falsch verstanden hast, aber mit der Option "-r" geht bei mir die Ersetzung.
Nö. "-r" bedeutet "extended regular expressions". Was das sind, kannst du gerne ergooglen. Ersetzen tut er beim ersten Befehl auch, allerdings ist die Regex da ne ganz andere (und matcht deshalb auch nicht...), weil viele Metazeichen anders/gar nicht interpretiert werden.
"Beweis":

echo 'foo'|sed -e 's/foo/bar/'
Aber glaube nicht mir:

man sed|less -p-r
oder:

sed --help|grep 'extended'

ContainerDriver
11-04-2008, 16:08
Ich verstehe nicht, auf was du hinaus willst. Ich kenne die Manpage von sed, hab da schon öfter reingeschaut...
Mir ist klar, dass man mit sed Textersetzungen vornehmen kann, auch ohne die Option "-r". Aber da der Threadersteller in seinem Regexp Fragezeichen ("?") verwendet, braucht er bei sed die Option "-r", damit es auf die gewünschte Art funktioniert.

WeenerChild
11-04-2008, 17:17
da der Threadersteller in seinem Regexp Fragezeichen ("?") verwendet, braucht er bei sed die Option "-r", damit es auf die gewünschte Art funktioniert.
Halte ich für ein Gerücht:

echo 'usr/pwd@omg'|sed -e 's/^\w\+\(\/\w\+\(@\w\+\)\?\)\?$/FAIL/'
Bzw es geht auch ganz ohne Fragezeichen:

echo 'usr/pwd@omg'|sed -e 's/^\w\+\(\/\w\+\(@\w\+\)\{0,1\}\)\{0,1\}$/FAIL/'
Wo genau braucht man dafür jetzt die "-r" Option? 0o
Die braucht man, wenn man das Fragezeichen nicht escapen will, aber das muss man bei den geschweiften ( {} ) sowie runden Klammern ( () ) auch.

Und wenn das ganze ein Missverständnis war, warum hast du nicht einfach nur zu diesem Satz hier:

Afaik Schwachfug, bei gnu sed sollte das für "extended regular expressions" stehen.
"Ja, genau das meinte ich ja auch, denn ohne extended regular expression syntax ist der gepostete reguläre Ausdruck so nicht 'funktionsfähig', bzw benötigt noch einige backslashes." -- gesagt, damit das Missverständnis sofort aufgelöst worden wäre? 0o
Oder halt spätestens bei meinem letzten Post mal nach "extended regular expressions" googlen können, um zu merken, dass ich exakt von derselben Sache rede wie du? Naja, Missverständnis aufgehoben.

ContainerDriver
11-04-2008, 17:44
Kein Grund sich aufzuregen :) Ich hab halt nicht verstanden, warum du dich eigentlich über das "-r" beschwert hast, nach der Manpage ist ja klar, für was die Option steht.

undefined
11-04-2008, 18:48
Damit wird der String aber nicht validiert.
Wozu auch, entweder benutzer,passwort,host und Kontext stimmen oder nicht.
Zumal dein Regexp ohnehin Probleme bekommt wenn das Passwort z.B.

123-.#?my:Pass
ist.

ContainerDriver
12-04-2008, 11:39
Der Threadersteller wollte es ja validieren. Ich denke in bestimmten Fällen kann es schon sinnvoller sein, den String zu überprüfen und eine Fehlermeldung auszugeben anstatt mit u.U. unbeabsichtigten Werten, die aus dem String gezogen werden, weiter zu arbeiten.

Dass der reguläre Ausdruck nicht immer greift ist natürlich richtig, aber vielleicht sind in den verwendeten Passwörtern auch keine Sonderzeichen erlaubt.

undefined
12-04-2008, 12:37
Selbst wenn sie nicht erlaubt sind brauchst du keinen Regexp. Du schaffst mehr Problem als Notwendig. Falsche Benutzereingabe etc. Wenn du mit awk jede Variable setzt macht den Rest das Passwort Program. In seinem Beispiel Code sehe ich das fast schon als Speicher verbraterei an weil du die Variablen ohnehin noch einmal abfragst ;)