ubuntuusers.de

Textfelder in Perl oder Bash Scripten

Status: Gelöst | Ubuntu-Version: Nicht spezifiziert
Antworten |

lexl

Avatar von lexl

Anmeldungsdatum:
6. Juni 2005

Beiträge: 69

Wohnort: Schwabenländle

Hallo,

ich möchte gerne ein Script (bash oder perl) schreiben das bei verschiedenen Tastatureingaben nur eine bestimmte maximale Anzahl von Zeichen zulässt. Bsp. erwarte ich eine Vorwahl, einer Telefonnummer, diese soll max 4 Zeichen Lang sein (nur so als Beispiel). Die Tastatureingabe sollte demnach auch nur 4 Zeichen erlauben.

Wie kann man so etwas am besten bewerkstelligen?

MfG, lexl

comm_a_nder

Avatar von comm_a_nder

Anmeldungsdatum:
5. Februar 2006

Beiträge: 2533

Wohnort: Dresden

man bash hat geschrieben:

      read [-ers] [-u fd] [-t timeout] [-a aname] [-p prompt] [-n nchars] [-d delim] [name ...]
              -n nchars
                     read returns after reading nchars characters rather than waiting for a complete line of input.

Allerdings kannst Du hier erstmal nicht so ohne weiteres auf einen Bestimmten Zeichenvorrat (zB nur Ziffern) beschränken.
Es wäre also prinzipiell besser, die Eingabe mit zB einem Regex zu checken und zur Not halt nochmal eingeben zu lassen.

lexl

(Themenstarter)
Avatar von lexl

Anmeldungsdatum:
6. Juni 2005

Beiträge: 69

Wohnort: Schwabenländle

Danke, dann werd ich das wohl mit regex machen.

Aber mal noch etwas anderes...

Beispiel:
Ein String sollte 28 Zeichen lang sein, der eigentliche String ist jedoch nur 10 Zeichen lang.
Die fehlenden Zeichen sollen mit Leerzeichen, Situationsbedingt vor oder hinter die 10 Zeichen aufgefüllt werden.

Gibt es in der Richtung eine Funktion für Perl oder ein anderes kleines Shell Script?
(Bin in der Sache noch nicht so fit drin, drum weiß ich nicht was im Prinziep alles schon existiert und was nacht - man muss ja das Rad nicht immer zweimal erfinden ☺)

MfG

MrDoubtfire

Anmeldungsdatum:
18. Oktober 2005

Beiträge: 210

Hallo lexl,

das ist ganz einfach:

#!/usr/bin/perl -w
use strict;
#             0----5----1----5----2----5----3
my $string1 = "                            ";
my $string2 = "abcdefghij";
my $string3 = $string2.substr($string1,length($string2));
my $string4 = substr($string1,0,length($string1)-length($string2)).$string2;
print "'$string3'\n'$string4'\n";

MrDoubtfire

lexl

(Themenstarter)
Avatar von lexl

Anmeldungsdatum:
6. Juni 2005

Beiträge: 69

Wohnort: Schwabenländle

Klasse, danke,

dürfte mit dürfte mit "substr" wohl performanter sein wie das was ich da gemacht habe...

#!/usr/bin/perl
use strict;

$eingabe = 32421342135;
$eingabe = &strmvs($eingabe,30);
print "$eingabe\n";	

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Leerzeichen voranstellen
sub strmvs
{
   my ($str, $length) = @_;			
   while (length($str) < $length){
      $str = " ".$str;
   }
   $str;
} 

MfG

comm_a_nder

Avatar von comm_a_nder

Anmeldungsdatum:
5. Februar 2006

Beiträge: 2533

Wohnort: Dresden

In der Bash (und auch in Perl) gibt es für diesen einfachen Fall doch printf.

INPUT="0123456789"
# rechtsbündig formatiert
printf '%28s' $INPUT
perl -e "printf '%28s', '$INPUT';"
# linksbündig formatiert
printf '%-28s' $INPUT
perl -e "printf '%-28s', '$INPUT';"

MrDoubtfire

Anmeldungsdatum:
18. Oktober 2005

Beiträge: 210

Hallo comm@nder,

hmh, ich dachte printf dient der formatierten Ausgabe ...
Was ist, wenn Du mit einer Programmvariable arbeiten musst bzw. wenn Du den Wert eben weiterverarbeiten willst ??

MrDoubtfire

comm_a_nder

Avatar von comm_a_nder

Anmeldungsdatum:
5. Februar 2006

Beiträge: 2533

Wohnort: Dresden

Dann schreibt man halt:

INPUT=$(printf '%28s' $INPUT)

e: und bei Perl nimmt man in diesem Fall wahrscheinlich sprintf statt printf

lexl

(Themenstarter)
Avatar von lexl

Anmeldungsdatum:
6. Juni 2005

Beiträge: 69

Wohnort: Schwabenländle

Da sieht man es wieder - "Viele Wege führen zum Ziel." ☺
Danke für die guten Vorschläge...

Aber wenn wir grad beim Thema Formatierte Strings sind, kann man eigentlich ohne weiteres der Shell sagen wie ein String ausgegeben werden soll (fett, unterstricken, ...)?

MfG, lexl

Sid_Burn

Anmeldungsdatum:
23. Oktober 2004

Beiträge: 2159

@lexl
Du solltest dir mal den "x" Operator anschauen. Dieser Multipliziert einen String.

$string = " " x 50;

Danach ist in $string ein 50 zeichen großer String der aus leerzeichen besteht. Dadurch kannst du dir deine Funktion sparen. Einen String zu definieren der wirklich 30 Leerzeichen groß ist so wie "MrDoubtFire" es gemacht hat würde ich auch nicht machen, dass ganze ist zu Fehler anfällig.

$string = "abc" x 3;

Danach würde in $string "abcabcabc" drin stehen. Ich hoffe die Funktionsweise ist klar geworden. Der Linke Operand wird als ein String gewertet und wird so oft wiederholt wie der Nummerische Ausdruck der als Rechter Operand steht. Du kannst also nicht einfach beide Werte Tauschen. Wenn dir dieser Abschnitt nicht klar ist, dann solltest du dir die Ausgabe von folgendes anschauen.

print 2 x 6, "\n";
print 6 x 2, "\n";

Ansonsten um zu überprüfen ob ein String eine bestimmte größe hat, kannst du "length" benutzen.

$string = "hallo";
print length $string, "\n";

Das würde "5" ausgeben, das ganze kannst du also auch so in einer if Kontrollstruktur schreiben.

if ( length $string != 10 )
{
    print "Zeichenkette muss 10 Zeichen groß sein\n";
}

Besser wäre wenn du das gleich mit der Eingabe koppelst und die Eingabe somit wiederholen lassen würdest.

{
    print "Bitte 10 Zeichen eingeben: ";
    chomp( $input = <STDIN> );
    redo if length $input != 10;
}

Ob 10 Zeichen eingegeben worden sind, kannst du auch mit einer regex Testen. Allerdings dürfte das length dafür Optimaler sein.

{
    print "Bitte 10 Zeichen eingeben: ";
    chomp( $input = <STDIN> );
    redo unless $input =~ /^.{10}$/;
}

Die regex wird erst dann Interessant wenn du beides Testen möchtest, z.B. ob nur Zahlen eingegeben worden sind, und davon eine bestimmte Menge. Hier müsste man genau 10 Zahlen eingeben.

{
    print "Bitte 10 Zahlen eingeben: ";
    chomp( $input = <STDIN> );
    redo unless $input =~ /^\d{10}$/;
}

Das ganze kannst du auch verwenden um einen Bereich von zeichen zu erlauben.

redo unless $input =~ /^\d{10,15}$/;   # 10 - 15 Zahlen sind erlaubt.
redo unless $input =~ /^\d{,33}$/;     # Minimum 0, maximal 33 Zahlen.
redo unless $input =~ /^\d{20,}$/;     # Minimal 20, maximal unendlich Zahlen.

lexl

(Themenstarter)
Avatar von lexl

Anmeldungsdatum:
6. Juni 2005

Beiträge: 69

Wohnort: Schwabenländle

@Sid Burn:

Danke für die ausführliche Hilfe...
Den x Operator kannte ich zwar schon, aber das hab irgendwie nihct dran gedacht den an der Stelle inzusetzten.
Der redo Operator ist mir allerdings neu. Scheint mir aber recht nütztlich zu sein.

Trotzdem noch eine Frage zu dem Konstrukt

{
    print "Bitte 10 Zeichen eingeben: ";
    chomp( $input = <STDIN> );
    redo if length $input != 10;
} 

Die zwei geschweifte Klammern leiten praktisch eine halbe Schleife ein, oder wie kann man das sehen?

PS.: Was für eine Entwicklungsumgebung könnt ihr mir eigentlich für Perl, Tk, etc. empfehlen - bekomm grad Lust in der Richtung mal etwas aktiver zu werden... Ein Texteditor wie vim reicht zwar im Grunde immer zum entwickeln, aber zum debuggen hab ich noch nichts "wirklich tolles" gefunden (außer vielleicht komodo)

Sid_Burn

Anmeldungsdatum:
23. Oktober 2004

Beiträge: 2159

Die zwei geschweifte Klammern leiten praktisch eine halbe Schleife ein, oder wie kann man das sehen?

Die zwei Klammern verhalten sich genauso wie ein if Konstrukt oder andere geschweifte klammern.
Nur haben sie halt keine if, while, for ... Bedingung. Ich weiß gar nicht mehr wie man das genau nennt, ich glaube das hieß dann Namenslose Schleife, oder so.

Innerhalb von Schleifen gibt es den "next, continue, last oder den redo" Operator.

Diese solltest du aber eigentlich kennen?

redo springt wieder zum Anfang der aktuellen Schleife, allerdings mit den Werten womit die Bearbeitung begonnen hat. next führt den continue Block aus. Das wäre bei einer for Schleife zum Beispiel das 3te Argument. Also normalerweise inkremtiert man dort eine Variable. Letztendlich überspringt man damit etwas. und last springt komplett aus der Schleife heraus.

http://perldoc.perl.org/functions/continue.html

Achso beinahe vergessen. Die Schleifen haben noch einen sehr wichtigen Vorteil. Sie besitzen einen eigenen lexikalischen Geltungsbereich. Das bedeutet das wenn du eine Variable mit "my" innerhalb der Geschweiften Klammern erzeugst, ist die Variable nur für diese Klammer gültig. Das ganze kann man auch noch mit "local" machen, und Variablen temporär überschreiben.

Die Klammern sind halt nützlich wenn du eine bestimmte variable z.B. nur sehr kurz und einmalig benutzt. Damit ist die variable dann nur innerhalb der Klammern gültig, und der Speicher den die variable benutzt hat, kann für etwas anderes benutzt werden.

$string = "Hallo, Welt!";

{
    local $string = "Immer der selbe Anfang.";
    my $s2 = "Test"

    print $string, "\n";
    print $s2, "\n";
}

print $string, "\n";
print $s2, "\n";

\––\–––

Bei der Frage mit der Entwicklungsumgebung kann ich dir nicht Helfen. Ich selber schreibe meine Skripte alle noch mit "mcedit". Ich selber wollte mir jetzt erstmal mehr vim Kentnisse aneignen und damit effektiv Programmieren.

Mit Tk kann ich dir auch noch nicht Helfen, da ich in Grafische Programmierung noch nicht Interessiert bin. Bei meinen Aufgaben ist mehr textbearbeitung wichtig, und Arbeite mich noch durch das Buch Reguläre Ausdrücke durch, mit dem ich aber fast durch bin. Danach kommt erstmal packages, module, netzwerkprogrammierung etc. Ist erstmal wichtiger als Klicki Bunti. *g*

manatsu

Avatar von manatsu

Anmeldungsdatum:
31. Dezember 2005

Beiträge: Zähle...

Zum Debuggen kann ich den Perl Debugger empfehlen. Einfach Perl mit Parameter -d aufrufen:

perl -d myProgram.pl


Mit mit [[b]h[/b]] kann man sich eine übersichtliche Hilfeseite mit allen wichtigen Kommandos ausgeben lassen.

Antworten |