Regular Expression Frage

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
knecht
Beiträge: 1214
Registriert: 08.01.2004 15:33:44
Wohnort: Berlin
Kontaktdaten:

Regular Expression Frage

Beitrag von knecht » 25.01.2005 09:22:22

Ich habe folgendes Problem mit einer RegEx

Ich will nur eine Eingabe in einer gewissen Form erzwingen:

Code: Alles auswählen

#!/bin/sh
#
#
echo
while [ "$start" !=  "[0-3][0-9]\ [0-1][0-9]\ [09][0-9]" ]; do
echo -n "Bitte Startdatum eingeben: (TT MM JJ) "
read start
done
Er läst mich aber nicht aus der Schleife raus, also ist meine Expression falsch.. Ich hab dann auch alle [ und ] mit Backslash probiert, dann alles ohne Backslash, habs nicht hinbekommen.

Wo ist mein kleiner Denkfehler ?

Danke
Sebastian
_________________________________________________
Linux HowTo's, Programmierung, Wallpapers und 3D:
http://www.neoBerserker.de

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

Beitrag von gms » 25.01.2005 09:30:44

naja, "!=" vergleicht Zeichenketten und keine RegEx.

Code: Alles auswählen

#!/bin/sh
#
while  !  echo "$start" | egrep "[0-3][0-9]\ [0-1][0-9]\ [09][0-9]"  ; do
echo -n "Bitte Startdatum eingeben: (TT MM JJ) "
read start
done

Benutzeravatar
knecht
Beiträge: 1214
Registriert: 08.01.2004 15:33:44
Wohnort: Berlin
Kontaktdaten:

Beitrag von knecht » 25.01.2005 09:35:30

du hast recht, vielen vielen Dank
naja, "!=" vergleicht Zeichenketten und keine RegEx
muß man halt auch erstmal wissen . . .
_________________________________________________
Linux HowTo's, Programmierung, Wallpapers und 3D:
http://www.neoBerserker.de

Benutzeravatar
knecht
Beiträge: 1214
Registriert: 08.01.2004 15:33:44
Wohnort: Berlin
Kontaktdaten:

Beitrag von knecht » 25.01.2005 11:42:29

Gleich noch ne blöde Frage . . .

Code: Alles auswählen

let A=jahre*365,25+monate*30,166666666667+tage
let B=jahre_start*365,25+monate_start*30,166666666667+tage_start
let C="(jahre*365,25+monate*30,166666666667+tage)-(jahre_start*365,25+monate_start*30,166666666667+tage_start)"
let D=A-B
echo $D
echo $C
Meiner logik nach sollte $C und $D doch das selbe enthalten, tun sie aber nicht !
C ergibt 8395
D ergibt 19
Ist doch ein und die selbe rechenaufgabe ?!?!?? wobei das egal ist, kann ja eben C nehmen, dann gehts.

Eine weitere Sache an der ich nicht weiterkomme: Wie kann ich eine Zahl durch eine Kommazahl teilen, also z.B. 8395 / 365,25 ausrechnen. Er nimmt das bei mir immer so als ob ich nur durch 365 Teile.
Ich kann ja auch 839500 / 36525 machen, aber macht man das so ?
_________________________________________________
Linux HowTo's, Programmierung, Wallpapers und 3D:
http://www.neoBerserker.de

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

Beitrag von gms » 25.01.2005 13:34:04

naja, die Shell erlaubt nur ganzzahlige Operationen

folgendes Script

Code: Alles auswählen

let X=3/4*4
echo X=$X

let X=4*1,25
echo X=$X
liefert folgendes "falsches" Ergebnis:

Code: Alles auswählen

X=0
X=4
[edit]
dieses Script

Code: Alles auswählen

X=`perl -e "print 3/4*4"`
echo X=$X

X=`perl -e "print 4*1.25"`
echo X=$X
liefert das richtige Ergebnis

Code: Alles auswählen

X=3
X=5
[/edit]

Benutzeravatar
knecht
Beiträge: 1214
Registriert: 08.01.2004 15:33:44
Wohnort: Berlin
Kontaktdaten:

Beitrag von knecht » 25.01.2005 14:43:08

Das kling gut ! Wobei ich erst das ganze noch in Klammern setzen mußte, aber so geht das jetzt:

Code: Alles auswählen

A=$(perl -e "print $jahre*365.25+$monate*30.166666666667+$tage")
echo A=$A
B=$(perl -e "print $jahre_start*365.25+$monate_start*30.166666666667+$tage_start")
echo B=$B
DIFF=$(perl -e "print $A-$B")
echo DIFF=$DIFF
Leider gings so nicht, aber egal:

Code: Alles auswählen

DIFF=$(perl -e "print ($jahre*365.25+$monate*30.166666666667+$tage)-($jahre_start*365.25+$monate_start*30.166666666667+$tage_start"))
Jetzt geht kein LET dahinter mehr mit diesen Variablen mehr, da er jetzt Kommastellen hat. Also muß ich die Variablen danach runden, nur wie ?
Ich hab in den Manpages von Shell und Bash mit "round" oder "rounding" als Suchbegriffe nichts gefunden. Damals unter Basic ging das ganz einfach, und wie gehts hier ?

danke
Sebastian
_________________________________________________
Linux HowTo's, Programmierung, Wallpapers und 3D:
http://www.neoBerserker.de

ernohl
Beiträge: 1248
Registriert: 04.07.2002 08:11:56
Wohnort: HL

Beitrag von ernohl » 25.01.2005 15:16:12

Rechne doch mit bc.

Code: Alles auswählen

$ echo 3*365.25 | bc
1095.75
Gruß
ernohl

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

Beitrag von gms » 25.01.2005 15:57:13

unter perl kannst du folgendermaßen runden:

Code: Alles auswählen

perl -e "print int(5/4)"

Benutzeravatar
puddlejumper
Beiträge: 58
Registriert: 22.01.2005 00:29:52

Beitrag von puddlejumper » 25.01.2005 19:24:51

Hi,

mmmhh, just my 2ct.:

ich persönlich würde in einem Shell-Script nicht mehrmals hintereinander eine Zeile mit perl -e ausführen. Dann würde ich versuchen, evtl. das ganze Script in Perl zu realisieren. In Fällen, wo ich nur ein wenig "Rechnen" muss, nehme ich in reinen Shell-Scripten dann z.B. expr

echo `expr 3 \* 3 \* 3`

Aber das ist halt alles persönlicher Geschmack. Eben wie auch in Perl, es gibt immer mehrere Wege...

Gruss,
PuddleJumper.

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

Beitrag von gms » 25.01.2005 20:43:06

puddlejumper hat geschrieben: Aber das ist halt alles persönlicher Geschmack. Eben wie auch in Perl, es gibt immer mehrere Wege...
vollig einverstanden
puddlejumper hat geschrieben:ich persönlich würde in einem Shell-Script nicht mehrmals hintereinander eine Zeile mit perl -e ausführen.
perl ist sicher langsamer als expr, jedoch schneller als bc.

Code: Alles auswählen

gms@gms1:~$ time for ((i=0; i<1000; i++)); do echo `echo 3 + $i + 3` | bc>x.log; done
real    0m3.933s
user    0m1.368s
sys     0m2.339s
gms@gms1:~$ time for ((i=0; i<1000; i++)); do perl -e "print 3+$i+3">x.log; done
real    0m3.287s
user    0m1.405s
sys     0m1.687s
gms@gms1:~$ time for ((i=0; i<1000; i++)); do echo `expr 3 \+ $i \+ 3`>x.log; done
real    0m1.617s
user    0m0.597s
sys     0m0.934s
und expr scheidet in diesem Fall aus, weil es keine Fließkomma Arithmetik beherrscht

Code: Alles auswählen

gms@gms1:~$ expr 25 \/ 3
8

Benutzeravatar
puddlejumper
Beiträge: 58
Registriert: 22.01.2005 00:29:52

Beitrag von puddlejumper » 25.01.2005 22:45:04

Hast natürlich Recht (obwohl ich das so auch nicht gedacht hätte) was ich aber damit zum Ausdruck bringen wollte war, dass man doch evtl. das ganze Script in Perl realisieren sollte...

P.S.: bei etwas umfangreicheren Shell-Scripten relativiert sich das sogar noch viel mehr:

joe@Dana-mobile:~/test$ time for ((i=0;i<1000;i++));do ./testscript.sh perl >> /dev/null ;done

real 0m48.855s
user 0m27.110s
sys 0m21.690s
joe@Dana-mobile:~/test$ time for ((i=0;i<1000;i++));do ./testscript.sh expr >> /dev/null ;done

real 0m45.052s
user 0m24.520s
sys 0m20.510s

Kommt auch immer auf die Script-Bedingungen an, für was, weshalb - Anforderungen, etc...
Der Laufzeitfaktor ist aber wohl meistens zu vernachlässigen, was mir dieser Test gezeigt hat.

Gruss,
PuddleJumper.

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

Beitrag von gms » 25.01.2005 23:52:07

puddlejumper hat geschrieben: Der Laufzeitfaktor ist aber wohl meistens zu vernachlässigen, was mir dieser Test gezeigt hat.
Ich wollte so einen "Performancetest" die längste Zeit schon durchführen. Dachte auch, daß ich solche Perleinzeiler in for-Schleifen vermeiden sollte und war von diesem Ergebnis auch überracht.

Benutzeravatar
knecht
Beiträge: 1214
Registriert: 08.01.2004 15:33:44
Wohnort: Berlin
Kontaktdaten:

Beitrag von knecht » 26.01.2005 12:31:16

Vielen Dank für die Hilfe:

Ich hab jetzt mit Perl und int() gearbeitet. Das ganze Script das ich geschrieben habe ist zum Berechnen der Tage, die zwischen einem eingegebenen Datum und dem heutigen Tag liegen.

Nichts tolles, aber hier ist es wenns jemand zufällig brauchen kann
http://knecht.homelinux.net/wwwshared/s ... ler-1.1.sh
_________________________________________________
Linux HowTo's, Programmierung, Wallpapers und 3D:
http://www.neoBerserker.de

Benutzeravatar
knecht
Beiträge: 1214
Registriert: 08.01.2004 15:33:44
Wohnort: Berlin
Kontaktdaten:

Beitrag von knecht » 27.01.2005 13:10:51

hab hier noch eine Art zum Berechnen gefunden:

Code: Alles auswählen

Da die Shell (hier Bash) nur minimal und kompliziert rechnen kann, hier ein Tipp, wie man sehr komfortabel auf der Konsole rechnen kann.
Hierzu wird ein Programm installiert und die Shell um einen Alias und eine Funktion bereichert.

Dieses Programm ist Octave - eine interaktive Sprache für numerische Berechnungen. Es sollten für jede Distribution Installationspakete vorhanden sein, ansonsten findet man die Quellen über die Homepage www.octave.org.

Octave kann interaktiv und über STDIN bedient werden. Da ich mir »octave« einfach nicht merken kann, habe ich mir einen Alias »calculator« angelegt. Um nur mal eben schnell eine Kleinigkeit auszurechnen, habe ich eine kleine Funktion "calc" geschrieben.


Diese kann man in der Datei /etc/profile oder besser in ~/.profile unterbringen.


# Rechnen in der Shell
alias
 calculator="octave -q"
function calc () {
 echo "$1" | calculator;
}

Dies richtet den Alias calculator ein, um die interaktive Octave-Shell zu öffnen, und die Funktion calc, um Octave über STDIN zu bedienen. Beispiel:

$ calc "1/3"
ans = 0.33333
_________________________________________________
Linux HowTo's, Programmierung, Wallpapers und 3D:
http://www.neoBerserker.de

Antworten