Match Regex in ksh


7

Ich möchte so etwas in KSH machen:

if (( $var = (foo|bar)[0-9]*$ )); then
    print "variable matched regex"
fi

Ist das überhaupt möglich?

Für die Aufzeichnung verwende ich Ksh Version M-11/16/88iauf einem Solaris 10-Computer.


4
Ist Ihnen klar, dass der reguläre Ausdruck [foo|bar]"ein einzelnes Zeichen aus der Menge (a, b, f, o, r, |) übereinstimmen" bedeutet? Wenn Sie "Match 'Foo' oder 'Bar'" (foo|bar)
meinen,

Stimmt, habe das nicht bemerkt. Ich werde entsprechend aktualisieren.
Rahm

Antworten:


8

Ksh hat reguläre Ausdrücke, jedoch nicht in der üblichen Syntax (nicht in der Version in Solaris 10 ).

if [[ $var = *@(foo|bar)*([0-9]) ]]; then 

Suchen Sie im Handbuch unter "Bedingte Ausdrücke" nach den Angaben in den Klammern und unter "Generierung von Dateinamen" nach der Mustersyntax.


Dies ist eine Musterübereinstimmung, keine Übereinstimmung mit regulären Ausdrücken (die den =~Operator verwendet).
Chepner

1
@chepner Es wird keine Regex-Syntax verwendet , aber es ist ein regulärer Ausdruck . Ksh-Muster enthalten alle Operatoren für reguläre Ausdrücke.
Gilles 'SO - hör auf böse zu sein'

4

Die Verwendung casemit Glob-Mustern funktioniert möglicherweise für Sie. Das zusammengesetzte Muster *(pattern-list)bedeutet "Entspricht null oder mehr Vorkommen der angegebenen Muster" und @(pattern-list)bedeutet "Entspricht genau einem der angegebenen Muster".

matcher() {
  typeset var="$1"
  case "$var" in
    *@(foo|bar)*([0-9])) print "$var matched" ;;
    *) print "$var did not match" ;;
  esac
}

for var in foo bar baz foo123 abc_foo132 abc_foo123z bar1 1bar1 1bar1a; do 
  matcher "$var"
done

Ausgänge:

foo matched
bar matched
baz did not match
foo123 matched
abc_foo132 matched
abc_foo123z did not match
bar1 matched
1bar1 matched
1bar1a did not match

2

Warum nicht egrep (1) verwenden ? Gibt Ihnen alles, was sich ein Regex-Benutzer wünschen kann:

 if echo "$var" | egrep -s '(foo|bar)[0-9]*$'    # -s means "silent"
  then
    ...

Zusätzlicher Hinweis für Solaris: Mit Solaris möchten Sie möglicherweise die Manpage auf egrep überprüfen. Es gibt eine andere egrep- Version /usr/xpg4/bin/egrep, die einige weitere Optionen unterstützt und sich in der Funktionalität unterscheidet, wenn es um erweiterte Regex-Inhalte geht.


1
Manchmal wird in Solaris auch GNU Egrep als gegrep installiert. Entweder von der Companion-CD oder von SunFreeWare und normalerweise in / opt / sfw / bin oder / usr / local / bin.
Tim Kennedy

@ Tim: stimmt, aber darauf würde ich mich nie verlassen. Aus meiner Erfahrung mit Kundenproduktionssystemen sollten Sie sich besser an das halten, was das Basisbetriebssystem bietet, da das, was wir für cool und hilfreich halten, in der Produktion oft nicht erlaubt ist. +1 sowieso ;-)
ktf

100% stimmten zu. Ich versuche immer Skripte / Programme / Perl-Module zu verwenden, die standardmäßig installiert sind. hält die Dinge tragbar.
Tim Kennedy

1

Ich habe so etwas mit gemacht sed. Ich weiß nicht, wie gut es ist, aber zumindest hat es funktioniert ^^

if [ -z "$(echo "$var" | sed -e 's/(foo|bar)[0-9]*$//')" ]; then
    print "variable matched regex"
fi

Sie müssen wie immer doppelte Anführungszeichen um Variablensubstitutionen setzen (andernfalls erhalten Sie bei einigen Eingaben, die Platzhalterzeichen oder Leerzeichen enthalten, falsche Ergebnisse oder Fehler). Selbst mit dem richtigen Anführungszeichen wird davon ausgegangen, dass die Eingabe keine neue Zeile enthält. Darüber hinaus ist Ihre Methode sehr kompliziert. grepist natürlicher , aber es gibt einen Weg, der in ksh eingebaut ist .
Gilles 'SO - hör auf böse zu sein'

0

Ich weiß, dass ich zu spät zur Party komme, aber anstelle der Lösung von ktf:

 if echo "$var" | egrep -s '(foo|bar)[0-9]*$'    # -s means "silent"
  then
    ...

Sie können auch verwenden

 if grep -q '(foo|bar)[0-9]*$' <<< "$var"        # -q means "quiet" ;-)
  then
    ...

Diese Technik mit dem <<<Bediener wird als Herestring bezeichnet . Ich sollte jedoch auch eine Warnung hinzufügen : Dies funktioniert NICHT in einer schreibgeschützten Umgebung (dh Sie erhalten hässliche Fehlermeldungen stderr), da für den Herestring eine temporäre Datei erforderlich ist, in die irgendwo geschrieben werden soll. Soweit ich weiß, echofunktioniert der "klassische" Weg mit und einer Pipe auch ohne Schreibgenehmigung.

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.