Eingabedaten prüfen

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
GregorS
Beiträge: 3174
Registriert: 05.06.2008 09:36:37
Wohnort: Freiburg
Kontaktdaten:

Eingabedaten prüfen

Beitrag von GregorS » 30.12.2009 16:11:17

Hallo zusammen!

Ich habe ein Shellskriptchen geschrieben und möchte Eingabedaten prüfen, konkret geht’s um Zeitangaben. Anstatt das mit if/then-Orgien zu erledigen, kam ich auf die Idee, dass es doch bestimmt ein Programm gibt, mit dem man Strings darauf prüfen kann, ob sie einem regulären Ausdruck entsprechen. Mit awk kann man das bestimmt ganz einfach, aber der Einsatz von awk entspräche wohl der Jagd auf Mücken mit Nuklearwaffen.

Gibt’s ein Progrämmchen, mit dem ich das erledigen kann? Oder bleibt mir nur etwas selbst Programmiertes?

Dank vorweg

Gregor
Wenn man keine Probleme hat, kann man sich welche machen. ("Großes Lötauge", Medizinmann der M3-Hopi [und sog. Maker])

Benutzeravatar
GoKi
Beiträge: 2068
Registriert: 04.07.2003 23:08:56
Lizenz eigener Beiträge: MIT Lizenz

Re: Eingabedaten prüfen

Beitrag von GoKi » 30.12.2009 16:25:47

man bash hat geschrieben: An additional binary operator, =~, is available, with the same precedence as == and !=. When it is used, the
string to the right of the operator is considered an extended regular expression and matched accordingly (as in
regex(3)). The return value is 0 if the string matches the pattern, and 1 otherwise. If the regular expression is
syntactically incorrect, the conditional expression's return value is 2. If the shell option nocasematch is
enabled, the match is performed without regard to the case of alphabetic characters. Any part of the pattern may
be quoted to force it to be matched as a string. Substrings matched by parenthesized subexpressions within the
regular expression are saved in the array variable BASH_REMATCH. The element of BASH_REMATCH with index 0 is the portion of the string matching the entire regular expression. The element of BASH_REMATCH with index n is the portion of the string matching the nth parenthesized subexpression.
MfG GoKi
:wq

Benutzeravatar
GregorS
Beiträge: 3174
Registriert: 05.06.2008 09:36:37
Wohnort: Freiburg
Kontaktdaten:

Re: Eingabedaten prüfen

Beitrag von GregorS » 30.12.2009 17:52:23

Hallo GoKi,

Danke für Deine Antwort! Es sieht ganz danach aus, dass ich mir mal einen Stapel Handbücher zulegen und lesen sollte.

Gruß

Gregor
Wenn man keine Probleme hat, kann man sich welche machen. ("Großes Lötauge", Medizinmann der M3-Hopi [und sog. Maker])

chrisbra
Beiträge: 122
Registriert: 19.10.2005 09:36:09
Wohnort: Sachsen-Anhalt
Kontaktdaten:

Re: Eingabedaten prüfen

Beitrag von chrisbra » 30.12.2009 20:22:25

GoKi hat geschrieben:
man bash hat geschrieben: An additional binary operator, =~, is available, with the same precedence as == and !=. When it is used, the
string to the right of the operator is considered an extended regular expression and matched accordingly (as in
regex(3)). The return value is 0 if the string matches the pattern, and 1 otherwise. If the regular expression is
syntactically incorrect, the conditional expression's return value is 2. If the shell option nocasematch is
enabled, the match is performed without regard to the case of alphabetic characters. Any part of the pattern may
be quoted to force it to be matched as a string. Substrings matched by parenthesized subexpressions within the
regular expression are saved in the array variable BASH_REMATCH. The element of BASH_REMATCH with index 0 is the portion of the string matching the entire regular expression. The element of BASH_REMATCH with index n is the portion of the string matching the nth parenthesized subexpression.
Unglücklicherweise gab es da bereits zwischen bash 3.1 und 3.2 IIRC inkompatible Änderungen. Das wäre für mich kein Grund mich auf so ein Verhalten zu verlassen. Dann lieber sed. Das ist dann portabel.
Meine Whishlist
:wq!

Benutzeravatar
GregorS
Beiträge: 3174
Registriert: 05.06.2008 09:36:37
Wohnort: Freiburg
Kontaktdaten:

Re: Eingabedaten prüfen

Beitrag von GregorS » 30.12.2009 20:48:32

chrisbra hat geschrieben: Unglücklicherweise gab es da bereits zwischen bash 3.1 und 3.2 IIRC inkompatible Änderungen. Das wäre für mich kein Grund mich auf so ein Verhalten zu verlassen. Dann lieber sed. Das ist dann portabel.
Interessante Info. Demnach muss ich mir wohl eher 'man sed' als 'man bash' antun.

Danke!

Gregor
Wenn man keine Probleme hat, kann man sich welche machen. ("Großes Lötauge", Medizinmann der M3-Hopi [und sog. Maker])

Benutzeravatar
GoKi
Beiträge: 2068
Registriert: 04.07.2003 23:08:56
Lizenz eigener Beiträge: MIT Lizenz

Re: Eingabedaten prüfen

Beitrag von GoKi » 30.12.2009 21:21:34

chrisbra hat geschrieben:Unglücklicherweise gab es da bereits zwischen bash 3.1 und 3.2 IIRC inkompatible Änderungen.
Ja, gab es. E14 in der FAQ.
ftp://ftp.cwru.edu/pub/bash/FAQ

Aber auch bei GNU-sed kann man Probleme haben, wenn man das Script dann mal auf Unix sed loslässt.
MfG GoKi
:wq

chrisbra
Beiträge: 122
Registriert: 19.10.2005 09:36:09
Wohnort: Sachsen-Anhalt
Kontaktdaten:

Re: Eingabedaten prüfen

Beitrag von chrisbra » 30.12.2009 22:02:34

GoKi hat geschrieben: Aber auch bei GNU-sed kann man Probleme haben, wenn man das Script dann mal auf Unix sed loslässt.
Nicht wenn man portabel scriptet.
Meine Whishlist
:wq!

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Re: Eingabedaten prüfen

Beitrag von gms » 30.12.2009 22:54:34

wenns um Portabilität geht, ist man überhaupt mit Perl, Python,.. besser bedient ( ganz lustige können auch M4 verwenden).

Benutzeravatar
Meillo
Moderator
Beiträge: 9254
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Eingabedaten prüfen

Beitrag von Meillo » 30.12.2009 23:06:28

GregorS hat geschrieben: Mit awk kann man das bestimmt ganz einfach, aber der Einsatz von awk entspräche wohl der Jagd auf Mücken mit Nuklearwaffen.
Awk ist für den Einsatzzweck sicher kein Overkill, zumindest nicht wenn du nicht für jeden String einzeln awk aufrufst.

Wenn du mehrere Strings gebündelt in awk stecken kannst, ist awk vermutlich der geeignetste Ansatz.


Ein Ansatz ohne viel zu überlegen:

Code: Alles auswählen

awk '
BEGIN {
	getline;
	if (! /RE/) {
		print "error";
	}
	# more checks
}' <<EOF
$var1
$var2
$var3
EOF
Use ed once in a while!

Benutzeravatar
GregorS
Beiträge: 3174
Registriert: 05.06.2008 09:36:37
Wohnort: Freiburg
Kontaktdaten:

Re: Eingabedaten prüfen

Beitrag von GregorS » 31.12.2009 03:34:16

Meillo hat geschrieben: Awk ist für den Einsatzzweck sicher kein Overkill, zumindest nicht wenn du nicht für jeden String einzeln awk aufrufst.
Tatsächlich nicht?!? Ich habe awk als Monster in Erinnerung. Aber meine Erfahrungen damit sind Äonen her (mein 386er mit 4 MB RAM wurde spürbar langsamer). Ich muss mir wohl nochmal Dein Seminar reinziehen und Literatur zu awk besorgen. Und zu einem Haufen anderer Sachen auch :-)

Gruß

Gregor
Wenn man keine Probleme hat, kann man sich welche machen. ("Großes Lötauge", Medizinmann der M3-Hopi [und sog. Maker])

Benutzeravatar
GregorS
Beiträge: 3174
Registriert: 05.06.2008 09:36:37
Wohnort: Freiburg
Kontaktdaten:

Re: Eingabedaten prüfen

Beitrag von GregorS » 31.12.2009 13:18:43

Hallo!

Nachdem ich mich ein bisschen mit regulären Ausdrücken und awk beschäftigt habe, dachte ich schon, dass ich die Prüfung meiner Eingabedaten damit erledigen könnte. Die Unterschiede zwischen "Basic" und "Extended" Regular Expressions machen’s mir aber echt schwer, da teilweise gleiche Zeichen unterschiedliche Bedeutungen haben können. So bedeutet z.B. "^" entweder "am Zeilenanfang" (extended r.e.) oder "nicht" (basic r.e.) - oder umgekehrt (grummel).

Manche Autoren machen’s besonders schlau, indem sie ihre Anleitungen einfach nur mit "Regular Expressions" überschreiben.

Darüber hinaus scheint das Matching wohl anders zu funktionieren, als ich dachte, denn das awk-Programm

Code: Alles auswählen

BEGIN {
  getline;
  if (! /[012][0-9]:[0-5][0-9]/)
  {
    print $0 " ist FALSCH";
  }
  else
  {
    print $0 " ist OK";
  }
}
erkennt sowohl "12:34" als auch "123:45" als "OK", wenn ich diese Strings per Pipe an "awk -f datei-mit-obigem-code" übergebe.

Könnte mich bitte jemand in die richtige Richtung schubsen und mir gute Online-Doku empfehlen? Fertige awk-Programme würden mir zwar kurzfristig helfen, ich würde das aber gerne selbst lösen, wobei mir allerdings folgende Frage in der Birne schwebt: Lohnt es sich denn überhaupt, sich mit den "Basic R. E." herumzuschlagen? Nur für awk?!?

Gruß und Dank vorweg

Gregor
Wenn man keine Probleme hat, kann man sich welche machen. ("Großes Lötauge", Medizinmann der M3-Hopi [und sog. Maker])

Benutzeravatar
GoKi
Beiträge: 2068
Registriert: 04.07.2003 23:08:56
Lizenz eigener Beiträge: MIT Lizenz

Re: Eingabedaten prüfen

Beitrag von GoKi » 31.12.2009 13:26:58

Du musst noch Anfang und Ende matchen, da sonst eben vor und nach deiner Regular-Expression noch Text stehen kann. z.B.

Code: Alles auswählen

/^[012][0-9]:[0-5][0-9]$/
Zuletzt geändert von GoKi am 31.12.2009 14:06:49, insgesamt 1-mal geändert.
MfG GoKi
:wq

chrisbra
Beiträge: 122
Registriert: 19.10.2005 09:36:09
Wohnort: Sachsen-Anhalt
Kontaktdaten:

Re: Eingabedaten prüfen

Beitrag von chrisbra » 31.12.2009 13:30:27

gms hat geschrieben:wenns um Portabilität geht, ist man überhaupt mit Perl, Python,.. besser bedient ( ganz lustige können auch M4 verwenden).
Du bindest Dir also lieber die Abhängigkeit von Perl/Python ans Bein? Ich mein, weder Perl noch Python müssen auf einem Unix installiert sein (SUSv3)

Wenn, dann implementiert man das Script eh am besten in $Scriptsprache komplett.
Meine Whishlist
:wq!

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Re: Eingabedaten prüfen

Beitrag von gms » 31.12.2009 13:49:20

chrisbra hat geschrieben:
gms hat geschrieben:wenns um Portabilität geht, ist man überhaupt mit Perl, Python,.. besser bedient ( ganz lustige können auch M4 verwenden).
Du bindest Dir also lieber die Abhängigkeit von Perl/Python ans Bein? Ich mein, weder Perl noch Python müssen auf einem Unix installiert sein (SUSv3)
ich habe noch kein Linux/Unix erlebt, bei dem kein Perl verfügbar gewesen wäre und ich bin schon lange auf diesem Gebiet tätig ( AIX, SunOS, MacOS, Linux(intel,powerpc,zOs) ) und sollte es mir wirklich einmal unterkommen, dann habe ich mir bis dahin schon ein Vielfaches an Zeit/Ärger,.. erspart, von dem was mich eine Perl-Installation kosten würde.
btw ich habe es schon des öfteren erlebt, daß ich awk,... nachinstallieren mußte, damit ein Script funktioniert. Nachdem diese Scripte in den meisten Fällen auch keine Abhängigkeiten definiert haben, kann man solche Dinge nur durch "Try and Error" bzw durch vorhergehendes Duchackern des Scripts herausfinden. Das ist auch nicht sehr toll
chrisbra hat geschrieben: Wenn, dann implementiert man das Script eh am besten in $Scriptsprache komplett.
klar

Gruß
gms

chrisbra
Beiträge: 122
Registriert: 19.10.2005 09:36:09
Wohnort: Sachsen-Anhalt
Kontaktdaten:

Re: Eingabedaten prüfen

Beitrag von chrisbra » 31.12.2009 14:22:42

GregorS hat geschrieben: Nachdem ich mich ein bisschen mit regulären Ausdrücken und awk beschäftigt habe, dachte ich schon, dass ich die Prüfung meiner Eingabedaten damit erledigen könnte. Die Unterschiede zwischen "Basic" und "Extended" Regular Expressions machen’s mir aber echt schwer, da teilweise gleiche Zeichen unterschiedliche Bedeutungen haben können. So bedeutet z.B. "^" entweder "am Zeilenanfang" (extended r.e.) oder "nicht" (basic r.e.) - oder umgekehrt (grummel).
nein. ^ bedeutet immer am Zeilenanfang. Nur in einer Kollection bedeutet es nicht also [^a] bedeutet jeder Buchstaube außer a und ^a bedeutet Zeilenanfang gefolgt von a.

GregorS hat geschrieben:

Code: Alles auswählen

BEGIN {
  getline;
  if (! /[012][0-9]:[0-5][0-9]/)
  {
    print $0 " ist FALSCH";
  }
  else
  {
    print $0 " ist OK";
  }
}
erkennt sowohl "12:34" als auch "123:45" als "OK", wenn ich diese Strings per Pipe an "awk -f datei-mit-obigem-code" übergebe.
Klar, weil [012][0-9] Matched halt auch auf die 23 von 123:45. Du mußt also den Match einschränken, z.B. mit ^[012][0-9]: oder besser ^[012]\?[0-9]

Ich würde dafür aber nicht awk starten, sondern dass ungefähr so die shell machen lassen:

Code: Alles auswählen

#!/bin/sh
OIFS="$IFS"
IFS=' :'
set -- $@
hour="$1"
min="$2"
sec="$3"

if [ -z "$hour" -o -z "$min" -o -z "$sec" ]; then
    echo "Format falsch angegeben"
    exit 2
fi

if [ "$hour" -gt 12 -o "$min" -gt 60 -o "$sec" -gt 60 ]; then
    echo "Keine gültige Zeit angegeben"
    exit 3
fi

cat <<EOF
Stunde: $hour
Minute: $min
Sekunde: $sec
EOF
GregorS hat geschrieben: wobei mir allerdings folgende Frage in der Birne schwebt: Lohnt es sich denn überhaupt, sich mit den "Basic R. E." herumzuschlagen? Nur für awk?!?
Es lohnt sich auf jeden Fall. grep, sed und vi sind ander populäre Programme, die nur die BRE implementieren.
Meine Whishlist
:wq!

Benutzeravatar
GregorS
Beiträge: 3174
Registriert: 05.06.2008 09:36:37
Wohnort: Freiburg
Kontaktdaten:

Re: Eingabedaten prüfen

Beitrag von GregorS » 31.12.2009 14:51:28

Hallo nochmal!

Vielen Dank für Eure Hilfe!

Inzwischen bin ich wieder ein Stückchen weiter und habe nur noch eine Frage, bevor ich mich hier vom Acker mache und auf den Jahreswechsel vorbereite:

Wenn ich beim Überfliegen der diversen Dokus nichts übersehen habe, kann man bei awk für einen Teilausdruck eines reg. Ausdrucks _nicht_ angeben, wie oft er erscheinen soll. D.h., dass ich für eine Überprüfung auf "h:mm" und "hh:mm" _zwei_ Blöcke mit zwei regulären Ausdrücken definieren muss.

Stimmt das so? Wenn ja: Was (zur Hölle) für Dinge haben die Erfinder der (basic) regulären Ausdrücke damit gemacht, dass sie so etwas nicht berücksichtigt haben?!?

Grüße

Gregor
Wenn man keine Probleme hat, kann man sich welche machen. ("Großes Lötauge", Medizinmann der M3-Hopi [und sog. Maker])

chrisbra
Beiträge: 122
Registriert: 19.10.2005 09:36:09
Wohnort: Sachsen-Anhalt
Kontaktdaten:

Re: Eingabedaten prüfen

Beitrag von chrisbra » 31.12.2009 16:56:04

GregorS hat geschrieben: Wenn ich beim Überfliegen der diversen Dokus nichts übersehen habe, kann man bei awk für einen Teilausdruck eines reg. Ausdrucks _nicht_ angeben, wie oft er erscheinen soll. D.h., dass ich für eine Überprüfung auf "h:mm" und "hh:mm" _zwei_ Blöcke mit zwei regulären Ausdrücken definieren muss.

Stimmt das so? Wenn ja: Was (zur Hölle) für Dinge haben die Erfinder der (basic) regulären Ausdrücke damit gemacht, dass sie so etwas nicht berücksichtigt haben?!?
Vielleicht solltest Du die Doku genauer lesen.

Code: Alles auswählen

~$ man grep
[...]
   Repetition
       A regular expression may be  followed  by  one  of  several  repetition
       operators:
       ?      The preceding item is optional and matched at most once.
       *      The preceding item will be matched zero or more times.
       +      The preceding item will be matched one or more times.
       {n}    The preceding item is matched exactly n times.
       {n,}   The preceding item is matched n or more times.
       {,m}   The preceding item is matched at most m times.
       {n,m}  The  preceding  item  is  matched at least n times, but not more
              than m times.
[...]
   Basic vs Extended Regular Expressions
       In  basic  regular expressions the meta-characters ?, +, {, |, (, and )
       lose their special meaning; instead use the  backslashed  versions  \?,
       \+, \{, \|, \(, and \).

       Traditional  egrep did not support the { meta-character, and some egrep
       implementations support \{ instead, so portable scripts should avoid  {
       in grep -E patterns and should use [{] to match a literal {.
[...]
Meine Whishlist
:wq!

Benutzeravatar
GregorS
Beiträge: 3174
Registriert: 05.06.2008 09:36:37
Wohnort: Freiburg
Kontaktdaten:

Re: Eingabedaten prüfen

Beitrag von GregorS » 02.01.2010 04:55:25

chrisbra hat geschrieben:
GregorS hat geschrieben: Wenn (...) nichts übersehen habe (...)
Vielleicht solltest Du die Doku genauer lesen.

Code: Alles auswählen

~$ man grep
[...]
Danke! Ich gucke bei Gelegenheit, ob das auch bei awk dokumentiert ist.

Gruß

Gregor
Wenn man keine Probleme hat, kann man sich welche machen. ("Großes Lötauge", Medizinmann der M3-Hopi [und sog. Maker])

chrisbra
Beiträge: 122
Registriert: 19.10.2005 09:36:09
Wohnort: Sachsen-Anhalt
Kontaktdaten:

Re: Eingabedaten prüfen

Beitrag von chrisbra » 02.01.2010 17:46:46

GregorS hat geschrieben: Danke! Ich gucke bei Gelegenheit, ob das auch bei awk dokumentiert ist.
http://www.gnu.org/manual/gawk/html_nod ... -Operators
Meine Whishlist
:wq!

Antworten