Dies ist mein erstes Bash-Skripting, daher mache ich wahrscheinlich leicht einen Fehler.
Im Grunde versuche ich, ein Skript zu schreiben, das die Gruppen eines Benutzers abruft und die Zugehörigkeit zu einer bestimmten Gruppe entsprechend protokolliert. Natürlich wird es noch mehr Funktionen geben, aber es hat keinen Sinn, das zu erstellen, wenn ich nicht einmal den regulären Ausdruck zum Laufen bekomme!
Bisher habe ich Folgendes:
#!/bin/bash
regex="^([a-zA-Z0-9\-_]+ : [a-zA-Z0-9\-_]+) (usergroup)$"
# example output
groups="username : username usergroup"
echo "$groups" >> /home/jrdn/log
if [[ "$groups" =~ $regex ]]; then
echo "Match!" >> /home/jrdn/log
else
echo "No match" >> /home/jrdn/log
fi
Überall, wo ich diesen regulären Ausdruck ausprobiert habe, funktioniert er. Aber im Bash-Skript wird immer nur das ausgegeben $groups
, gefolgt von No match
. Kann mir also jemand sagen, was daran falsch ist?
Antwort1
Aus man 7 regex
:
Ein Klammerausdruck ist eine Liste von Zeichen, die in "[]" eingeschlossen sind. …
… Um ein wörtliches „-“ einzuschließen, machen Sie es zum ersten oder letzten Zeichen…. [A]lle anderen Sonderzeichen, einschließlich „\“, verlieren innerhalb eines Klammerausdrucks ihre besondere Bedeutung.
Beim Versuch, den regulären Ausdruck mit egrep einzugeben, tritt ein Fehler auf:
$ echo "username : username usergroup" | egrep "^([a-zA-Z0-9\-_]+ : [a-zA-Z0-9\-_]+) (usergroup)$"
egrep: Invalid range end
Hier ist eine einfachere Version, die auch einen Fehler erzeugt:
$ echo 'hi' | egrep '[\-_]'
egrep: Invalid range end
Da \
nichts Besonderes ist, handelt es sich um einen Bereich, genau wie [a-z]
wäre. Sie müssen Ihr -
am Ende einfügen, wie [_-]
oder:
echo "username : username usergroup" | egrep "^([a-zA-Z0-9_-]+ : [a-zA-Z0-9_-]+) (usergroup)$"
username : username usergroup
Dies sollte unabhängig von Ihrer Libc-Version (entweder in egrep oder in bash) funktionieren.
bearbeiten:Dies hängt tatsächlich auch von Ihren Gebietsschemaeinstellungen ab. Die Manpage warnt davor:
Bereiche hängen stark von der Sortierreihenfolge ab, portable Programme sollten es vermeiden, sich auf sie zu verlassen.
Zum Beispiel:
$ echo '\_' | LC_ALL=en_US.UTF8 egrep '[\-_]'
egrep: Invalid range end
$ echo '\_' | LC_ALL=C egrep '[\-_]'
\_
Auch wenn kein Fehler aufgetreten ist, bewirkt es natürlich nicht das, was Sie möchten:
$ echo '\^_' | LC_ALL=C egrep '^[\-_]+$'
\^_
Es ist ein Bereich, der in ASCII die Zeichen \
, [
, ^
, und umfasst _
.
Antwort2
Allgemeine Regel bei regulären Ausdrücken (und allen Fehlern in größeren Codeteilen): Reduzieren Sie den Code und bauen Sie ihn schrittweise neu auf oder verwenden Sie die Halbierung – was auch immer für Sie besser funktioniert.
In diesem Fall war der Unterstrich der Übeltäter. Durch das Maskieren mit einem Backslash hat es funktioniert.