IF Vergleich

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Benutzeravatar
pinguino
Beiträge: 147
Registriert: 23.01.2007 23:11:46

IF Vergleich

Beitrag von pinguino » 01.09.2009 16:29:01

Hallo,

ich versuche ein String zu vergleichen:

1ster Fall : var1=123

2ter Fall: var1=0FF

Code: Alles auswählen

#!/bin/bash

var1=123

if [[  "$var1"  !=  +\([0-9]\) ]] 

then

var2=` echo "obase=10; ibase=16; $var1"  | bc `

echo "$var2"

else

echo " Keine Hexadezimalzahl"

fi
Hier wird immer var2 berechnet, obwohl das Muster nicht paßt. 8O
Gruß

Pinguino

>>Nota bene<<

Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Re: IF Vergleich

Beitrag von Duff » 01.09.2009 17:01:17

var2 soll doch immer dann berechnet werden, wenn das Muster nicht passt (!=).

Wobei mir dein "Muster" nicht so ganz zusagt. Bei Strings würde ich das Muster auf jeden Fall in "" setzen.
Oh, yeah!

Benutzeravatar
hikaru
Moderator
Beiträge: 13950
Registriert: 09.04.2008 12:48:59

Re: IF Vergleich

Beitrag von hikaru » 01.09.2009 17:26:15

Du prüfst hier auf eine Regex, da brauchst du den Operator "=~". Außerdem stimmt die Syntax nicht ganz. Wenn ich richtig verstehe, was das Script machen soll, dann tausche mal die If-Zeile aus:

Code: Alles auswählen

if [[  "$var1" =~ "[0-9A-F]+" ]]
Edit:
Gibt es eigentlich eine Negation von "=~" die nicht auf das Invertieren der Regex hinausläuft? Die für mich naheliegenden Schüsse ins Blaue ("!=~" und "!~") sind es offenbar nicht.

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

Re: IF Vergleich

Beitrag von gms » 01.09.2009 18:03:53

hikaru hat geschrieben:Du prüfst hier auf eine Regex, da brauchst du den Operator "=~".
entweder mit Regex

Code: Alles auswählen

gms1 ~ # cat y.sh
#!/bin/bash
isnumber() {
  if [[ "$1" =~ ^[0-9]+$ ]]; then
    echo "$1 is a number"
  else
    echo "$1 is NOT a number"
  fi
}

isnumber 123
isnumber off
gms1 ~ # bash y.sh
123 is a number
off is NOT a number
oder mit Pattern Matching

Code: Alles auswählen

gms1 ~ # cat x.sh
#!/bin/bash

shopt -s extglob

isnumber() {
  if [[ $1 == +([0-9]) ]]; then
    echo "$1 is a number"
  else
    echo "$1 is NOT a number"
  fi
}

isnumber 123
isnumber off
gms1 ~ # bash x.sh
123 is a number
off is NOT a number
gms1 ~ #                
Gruß
gms
Zuletzt geändert von gms am 01.09.2009 18:06:41, insgesamt 2-mal geändert.

Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Re: IF Vergleich

Beitrag von Duff » 01.09.2009 18:04:11

Ok, sorry. Habe mich vertan.

Müsste so aussehen:

Code: Alles auswählen

if [[  $var1 =~ [0-9A_Z]+ ]] 
Zuletzt geändert von Duff am 01.09.2009 18:30:10, insgesamt 1-mal geändert.
Oh, yeah!

Benutzeravatar
pinguino
Beiträge: 147
Registriert: 23.01.2007 23:11:46

Re: IF Vergleich

Beitrag von pinguino » 01.09.2009 18:04:44

das Zeichen "=~" muß nicht unbedingt dabei sein aber ich hatte Probleme mit Regex. Jetzt funktioniert:

Code: Alles auswählen

var1=123

var2=` echo "obase=10; ibase=16; $var1"  | bc `

if [[  "$var1"  ==  [0-9][0-9]*  ]]

then

echo " Keine Hexadezimalzahl"

else

echo "$var2"

fi
Gruß

Pinguino

>>Nota bene<<

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

Re: IF Vergleich

Beitrag von gms » 01.09.2009 18:09:49

pinguino hat geschrieben:das Zeichen "=~" muß nicht unbedingt dabei sein aber ich hatte Probleme mit Regex.
wenn du RegEx verwendest möchtest, dann muß in der Bash ein "=~" verwendet werden, was du meinst ist das einfach Pattern Matching der Bash, das funktioniert ohne diesem Zeichen

Gruß
gms

Benutzeravatar
pinguino
Beiträge: 147
Registriert: 23.01.2007 23:11:46

Re: IF Vergleich

Beitrag von pinguino » 01.09.2009 18:40:01

was du meinst sind "extended regular expressions" aber was ich verwende, sind "basic regular expressions"
Siehe hier
Gruß

Pinguino

>>Nota bene<<

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

Re: IF Vergleich

Beitrag von gms » 01.09.2009 19:02:13

pinguino hat geschrieben:was du meinst sind "extended regular expressions" aber was ich verwende, sind "basic regular expressions"
Siehe hier
ja ich meine die "extended regular expressions", welche in der Shell den '=~' Operator benötigt
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 expres‐
sion and matched accordingly (as in regex(3)).
wenn du in der Shell diesen Operator nicht verwenderst, werden keine "Basic regular expressions" verwendet, wie sie in dem von die geposteten Link definiert werden, sondern wird ein einfaches Pattern Matching verwendet, wie es in der Dokumentation der Shell definiert wird :wink:
pinguino hat geschrieben: Jetzt funktioniert:
mit welchen Test-Cases hast du das eigentlich überprüft ? :wink:
Gruß
gms

Benutzeravatar
pinguino
Beiträge: 147
Registriert: 23.01.2007 23:11:46

Re: IF Vergleich

Beitrag von pinguino » 01.09.2009 19:08:05

wo steht das?
Gruß

Pinguino

>>Nota bene<<

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

Re: IF Vergleich

Beitrag von gms » 01.09.2009 19:09:11

man bash hat geschrieben: When the == and != operators are used, the string to the right
of the operator is considered a pattern and matched according to
the rules described below under Pattern Matching.

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

Re: IF Vergleich

Beitrag von gms » 01.09.2009 19:15:50

verstehe mich richtig, das klingt vielleicht nach Wortglauberei, soll es aber nicht sein und genau dein gepostetes angeblich funktionierendes Script zeigt den Unterschied:
als RegEx bedeuted "[0-9][0-9]*" etwas anderes als beim Pattern Matching der Shell

Gruß
gms

Benutzeravatar
pinguino
Beiträge: 147
Registriert: 23.01.2007 23:11:46

Re: IF Vergleich

Beitrag von pinguino » 01.09.2009 19:28:31

[0-9][0-9]* ist ein regulärer Ausdruck. Wenn du möchtest kann ich Dir das O'Reilly Buch hochladen
Gruß

Pinguino

>>Nota bene<<

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

Re: IF Vergleich

Beitrag von gms » 01.09.2009 19:35:19

ok, du willst es nicht schnallen, ich gebs auf

Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Re: IF Vergleich

Beitrag von Duff » 02.09.2009 08:01:46

Ich finde die Diskussion interessant und informativ...
Oh, yeah!

Benutzeravatar
hikaru
Moderator
Beiträge: 13950
Registriert: 09.04.2008 12:48:59

Re: IF Vergleich

Beitrag von hikaru » 02.09.2009 08:59:49

gms hat geschrieben:als RegEx bedeuted "[0-9][0-9]*" etwas anderes als beim Pattern Matching der Shell
Um das ganze mal aufzudröseln.

Als Regex bedeutet das:
Zahl - gefolgt von Null bis unendlich vielen Zahlen.

Als Shell-Pattern:
Zahl - gefolgt von Zahl - gefolgt von beliebigem String.

Was nun wie bei welchem Operator matcht kann jeder selbst testen.

Benutzeravatar
pinguino
Beiträge: 147
Registriert: 23.01.2007 23:11:46

Re: IF Vergleich

Beitrag von pinguino » 02.09.2009 12:58:49

ich bin mit meiner Nachforschung ein bißchen weitergekommen :mrgreen:

Im Prinzip hat gms teilweise Recht.

wenn ich

Code: Alles auswählen

"$var1"  ==  [0-9][0-9]*
eingebe, dann wird z.B 12FF auch angenommen, was falsch ist. Wenn ich aber:

Code: Alles auswählen

"$var1"  =~  [0-9][0-9]*
eingebe, versteht Bash das nicht als regulären Ausdruck ABER!!!

wenn ich

Code: Alles auswählen

"$var1"  =~  ^[0-9][0-9]*$
eingebe, dann wird alles als regulären Ausdruck interpretiert und nur dann.
Gruß

Pinguino

>>Nota bene<<

Benutzeravatar
hikaru
Moderator
Beiträge: 13950
Registriert: 09.04.2008 12:48:59

Re: IF Vergleich

Beitrag von hikaru » 02.09.2009 13:22:19

pinguino hat geschrieben:wenn ich

Code: Alles auswählen

"$var1"  ==  [0-9][0-9]*
eingebe, dann wird z.B 12FF auch angenommen, was falsch ist.
Nein, es ist nicht falsch, nur deine Interpretation des Operators ist es:

Code: Alles auswählen

Zahl - gefolgt von Zahl - gefolgt von beliebigem String.
  1                 2                             FF
pinguino hat geschrieben:Wenn ich aber:

Code: Alles auswählen

"$var1"  =~  [0-9][0-9]*
eingebe, versteht Bash das nicht als regulären Ausdruck
Weil nicht klar ist wo die Regex anfängt und aufhört. Gehören beide Leerzeichen zwischen "=~" und "[0-9]" dazu, oder nur eines, oder keines?
pinguino hat geschrieben:wenn ich

Code: Alles auswählen

"$var1"  =~  ^[0-9][0-9]*$
eingebe, dann wird alles als regulären Ausdruck interpretiert
Weil der Ausdruck nun terminiert ist.
pinguino hat geschrieben:und nur dann.
Nein. Das funktioniert formal auch, denn auch hier ist der Ausdruck terminiert:

Code: Alles auswählen

"$var1"  =~  "[0-9][0-9]*"
Das ist aber ein anderes Pattern, das unter Umständen ein anderes Ergebnis liefert.

Benutzeravatar
pinguino
Beiträge: 147
Registriert: 23.01.2007 23:11:46

Re: IF Vergleich

Beitrag von pinguino » 02.09.2009 13:26:10

ich meinte mit falsch, daß meine Bedingungen für die Aufgabe nicht erfüllt waren
Gruß

Pinguino

>>Nota bene<<

Benutzeravatar
pinguino
Beiträge: 147
Registriert: 23.01.2007 23:11:46

Re: IF Vergleich

Beitrag von pinguino » 02.09.2009 13:31:44

hikaru hat geschrieben:...
pinguino hat geschrieben:und nur dann.
Nein. Das funktioniert formal auch, denn auch hier ist der Ausdruck terminiert:

Code: Alles auswählen

"$var1"  =~  "[0-9][0-9]*"
Das ist aber ein anderes Pattern, das unter Umständen ein anderes Ergebnis liefert.
Genau, das ist das Problem. Das liefert ein anderes Ergebnis. z.B 12FF liefert als Ausgabe "Keine Hexadezimal", was falsch für meine Aufgabe wäre
Gruß

Pinguino

>>Nota bene<<

Benutzeravatar
hikaru
Moderator
Beiträge: 13950
Registriert: 09.04.2008 12:48:59

Re: IF Vergleich

Beitrag von hikaru » 02.09.2009 14:03:37

pinguino hat geschrieben:Genau, das ist das Problem. Das liefert ein anderes Ergebnis. z.B 12FF liefert als Ausgabe "Keine Hexadezimal", was falsch für meine Aufgabe wäre
Deshalb war ja mein ursprünglicher Vorschlag auch dieser:

Code: Alles auswählen

if [[  "$var1" =~ "[0-9A-F]+" ]]
Wie fängst du denn jetzt Hex-Zahlen > 9 ab?

Benutzeravatar
pinguino
Beiträge: 147
Registriert: 23.01.2007 23:11:46

Re: IF Vergleich

Beitrag von pinguino » 02.09.2009 14:16:23

Für meine Aufgabe wäre das :

Code: Alles auswählen

if [[  "$var1" =~ "[0-9A-F]+" ]]
nicht gültig, da nur Zahlen erlaubt sind
Gruß

Pinguino

>>Nota bene<<

Benutzeravatar
pinguino
Beiträge: 147
Registriert: 23.01.2007 23:11:46

Re: IF Vergleich

Beitrag von pinguino » 02.09.2009 14:23:02

wenn du "" setzt, wird alles als Pattern verstanden und nicht als ein regulärer Ausdruck. ^ und $ sind entscheidend

Beispiel

Code: Alles auswählen

"[0-9][0-9]*"
Hier wird auch 12FF (Buschstaben) erlaubt.

In diesem Fall nie

Code: Alles auswählen

^[0-9][0-9]*$
Gruß

Pinguino

>>Nota bene<<

Danielx
Beiträge: 6419
Registriert: 14.08.2003 17:52:23

Re: IF Vergleich

Beitrag von Danielx » 02.09.2009 14:57:14

pinguino hat geschrieben:In diesem Fall nie

Code: Alles auswählen

^[0-9][0-9]*$
Das lässt sich auch kürzer schreiben:

Code: Alles auswählen

^[0-9]+$
hikaru hat geschrieben:Deshalb war ja mein ursprünglicher Vorschlag auch dieser:

Code: Alles auswählen

if [[  "$var1" =~ "[0-9A-F]+" ]]
Hm, das funktioniert bei mir irgendwie nicht.

Gruß,
Daniel

Benutzeravatar
hikaru
Moderator
Beiträge: 13950
Registriert: 09.04.2008 12:48:59

Re: IF Vergleich

Beitrag von hikaru » 02.09.2009 15:01:29

Danielx hat geschrieben:Hm, das funktioniert bei mir irgendwie nicht.
Auf dem openSuse 10.2 mit bash 3.1.17 vor dem ich hier sitze funktioniert es syntaktisch und matcht Hex-Zahlen.
Ich erinnere mich dunkel an Syntaxänderungen zwischen Bash 3.1 und 3.2, vielleicht trifft das hier zu?

Antworten