|
|
 |

|

 |

| Community » Perl: Allgemeines Forum |
|
@ARGV??? wie was wo und warum?
|
Seitenanfang |
Tag zusammen, kann mir vielleicht einer hierbei weiter helfen??? Ich soll ein bestehendes Script verändern, nur weiß ich nicht genau wie ich das machen soll.<Ein bisschen interessanter ist vielleicht eine Verallgemeinerung dieses Programmes. Wie möchten die Suchstrings als Argumente übergeben. Angenommen das Programm heisse countlines. Bei einem Aufruf countlines first second etc werden die Argumente im Array @ARGV abgespeichert. Somit ist $ARGV[0] gleich first, $ARGV[1] gleich second und $ARGV[2] gleich etc. Aendere das Programm, sodass es ein Argument akzeptiert und nur diejenigen Zeilen zählt, welche diesen String enthalten. Setze diese Vorkommnisse in Klammern. Damit wird countlines du unter anderem die folgende Zeile ausgeben: 022Blackcurrant-Büchse (du)rch die Luft, die er mit einem Hechtsprung auf den> Ich hab keine Ahnung was und wie ich @ARGV verwenden soll. Das ist das zu benutzende script, wenn man das überhaupt so nennen darf ;-) #!/usr/local/bin/perl # $file = '/home/geschichte.txt'; open (INFO, $file); $line = <INFO>; $nummer = 0; @doppelt = "aa "; while ($line = <INFO>) { if ($line !~ s/(|bb|cc|dd|ee|ff|gg|hh|ii|jj|kk|ll|mm|nn|oo|pp|qq|rr|ss|tt|uu|vv|ww|xx|yy|zz )//g) { print "$line \t"; next; } $nr = sprintf("%03d", ++$nummer); print "$nr $line"; }
Vielen danke schon mal für eure mühe mfg suchender
Datum: 21.09.2005-13:50

|
re: @ARGV??? wie was wo und warum?
|
Seitenanfang |
| Hi, eine Hinweis auf @ARGV findest Du unter dem Punkt "Vordefinierte Listen und Hashes" auf selfHTML. http://de.selfhtml.org/perl/sprache/vordefiniert.htm#skalare Ein kleiner snippet:
my $i = 0; my $k = 0; my $z = 0; my @lines = (); my $file = '/home/geschichte.txt'; print "\nSuchmuster waren: "; foreach(@ARGV) { ...print "$_, "; } print "\n\n"; open(INFO, "<".$file); while(<INFO>) { ...$lines[$i] = $_; ...$i++; } close(INFO);$k = @ARGV; for($i = 0; $i < $k; $i++) { ...$z = 0; ...foreach(@lines) ...{ ......if($_ =~ s/($ARGV[$i])/($1)/g) ......{ .........$_ =~ s/^\d{3}//; .........$_ = sprintf("%3d %s\n", ++$z, $_); ......} ...} } $z = 0; foreach(@lines) { ...if(/^\d{3}/) ...{ ......print $_; ......$z++; ...} } print "\nIn $z Zeilen wurden Muster gefunden.\n";
Erklärung: Punkte symbolisieren Leerzeichen, bzw. 3 einen Tab. Zunächst wird die komplette Datei Zeile für Zeile in einen Array geladen und das Handle gleich wieder geschlossen. Dann wird in einer for-Schleife jedes Argument abgearbeitet. Jede Zeile des Arrays wird auf das aktuelle Suchmuster ($ARGV[$i]) geprüft und gegebenenfalls geklammert. $z wird für jedes Argument wieder auf Null gesetzt, damit die richtige Zeilennummer am Anfang steht. Sollte im vorherigen Durchlauf in der aktuellen Zeile schon einmal ein Muster gefunden worden sein, steht eine Zahl am Anfang. Diese wird dann gelöscht, damit sie im Falle von verschiedenen gefundenen Mustern auf einer Zeile nicht mehrfach ausgegeben wird. Abschließend wird der Array noch einmal durchlaufen und gecheckt, in wie vielen Zeilen Zahlen am Anfang stehen, damit sie gezählt werden können.Eines ist in dem snippet aber nicht abgedeckt! Sollten in der Datei von Anfang an Zeilen existieren, die mit drei Zahlen beginnen, dann müssen diese erst in einem Hilfsarray gemerkt, temporär geändert und nach der Suche / Zählung wieder zurück geändert werden. Sonst stehen an diesen Stellen irgendwelche Zeilennummern. Dadurch könnte der Sinn eines Textes entstellt werden. -uw
Datum: 21.09.2005-17:02

|
re: @ARGV??? wie was wo und warum?
|
Seitenanfang |
| Ganz schön kompliziert... Die Aufgabe lässt sich viel leicher lösen:
#!/usr/local/bin/perl # use strict; use warnings;my $file = '/home/geschichte.txt'; my $regex = join("|",@ARGV); my $nummer = 0; open (INFO, $file) or die $!; while (my $line = <INFO>){ if ($line =~ $regex){ print sprintf("%03d %s", ++$nummer,$line); } } close INFO;
Datum: 22.09.2005-08:06

|
re: @ARGV??? wie was wo und warum?
|
Seitenanfang |
oder sogar (und inklusive des verlangten Klammerns des gefundenen Ausdrucks):
while(<INFO>){ printf("%03d %s", ++$nummer,$_) if s/($regex)/\($1\)/gi; }
svenXY
Datum: 22.09.2005-09:57

|
re: @ARGV??? wie was wo und warum?
|
Seitenanfang |
| Hi, schön und gut, aber es sollte ja auch ein wenig anschaulisch sein. -uw
Datum: 22.09.2005-10:09

|
re: @ARGV??? wie was wo und warum?
|
Seitenanfang |
| so, hier mal eben schnell die Lösung des Problems. #!/usr/local/bin/perl # $file = 'geschichte.txt'; open (INFO, $file); $line = <INFO>; $nummer = 0; $pattern; $anzahlargv = @ARGV; ### pattern erstellen foreach(@ARGV) { $pattern .= "$_\|"; } ### | hinter letztem pattern entfernen chop $pattern; while ($line = <INFO>) { if ($line !~ s/($pattern)/\($1\)/g) { print "$line \t"; next; } $nr = sprintf("%03d", ++$nummer); print "$nr $line"; }
Datum: 22.09.2005-10:40

|
re: @ARGV??? wie was wo und warum?
|
Seitenanfang |
Die Zeile: $anzahlargv = @ARGV; ist allerdings nicht notwendig. Könnt Ihr rauslöschen.
Datum: 22.09.2005-10:41

|
re: @ARGV??? wie was wo und warum?
|
Seitenanfang |
| Hi Haniball, Leider funktioniert Deine Lösung nicht. Ich bekomme Folgendes Ergebnis:
$ perl search_schlecht.pl Wort 001 Die ist meine Datei geschichte.txt, Zeile 2. (Wort) Die ist meine Datei geschichte.txt, Zeile 3. anderes Die ist meine Datei geschichte.txt, Zeile 4. Test 002 Die ist meine Datei geschichte.txt, Zeile 5. Test (Wort) Die ist meine Datei geschichte.txt, Zeile 6. Die ist meine Datei geschichte.txt, Zeile 7. 003 Die ist meine Datei geschichte.txt, Zeile 8. (Wort) Die ist meine Datei geschichte.txt, Zeile 9. Die ist meine Datei geschichte.txt, Zeile 10. Die ist meine Datei geschichte.txt, Zeile 11. Die ist meine Datei geschichte.txt, Zeile 12.
- In Zeile 4 weist Du die erste Zeile Deiner Datei bereits $line zu, bearbeitest sie aber dann nicht. Sie ist für die while Schleife bereits verloren (Deswegen fehlt sie im Ergebnis). Du solltest diese Zeile einfach weglassen. - Was soll das "print "$line \t"" bezwecken? So wie es da steht, wird jede Zeile, in der es keine Ersetzung gab, ausgegeben (mit dem Newline, das die Zeile ja noch hat) und dahinter (also am Anfang der neuen Zeile) ein Tabulator (\t), so dass die folgende Zeile um einen Tab eingerückt erscheint. Da nur die Zeilen ausgegeben werden sollen, in denen es Das Wort gibt, solltest Du das ebenfalls einfach weglassen. - Warum baust Du $pattern so umständlich (join ist da echt besser geeignet)? - Wo überprüfst Du, ob sich das file überhaupt korrekt öffnen liess (oder überhaupt vorhanden ist)? - Wie sieht es mit use strict; use warnings; aus und den (positiven) Konsequenzen, die sich für den Programmierstil ergeben?Bitte nimm es nicht persönlich, es geht allein darum, dass wir alle besseren code produzieren. Gruss, svenXY
Datum: 22.09.2005-11:13

|
re: @ARGV??? wie was wo und warum?
|
Seitenanfang |
In der Aufgabe ging es darum den vorhandenen code abzuändern und NUR die Änderungen einzubringen damit dies funktioniert. Mit dem join ist eine deutlich bessere Lösung den | einztubringen, daran hab ich auf die schnelle nicht gedacht.Das $line = <INFO>; habe ich komplett übersehen. Du musst verstehen das ich hier eine eigene Firma habe und für die Anpassung dieses scripts nur wenig zeit vorhen hatte, also verzei mir ;). Hier ist übrigens ein Ergebniss mit meinem vorherigen code: Powermac:~ christian$ perl ./test.pl christian ist 001 das hier (ist) eine geschichte 002 lalala (christian) (ist) lieb 003 wer b(ist) du Der Tab ist übrigens ebenfalls in dem ausgangscode. Ich habe mich darüber auch gewundert, jedoch dieses Tab zu entfernen war nicht die Aufgabe. Hier nun die bessere variante OHNE den Code zu sehr zu verändern und OHNE Code einzubaun der den Ablauf des scriptes überprüft (und übersichtlicher): #!/usr/local/bin/perl # $file = 'geschichte.txt'; open (INFO, $file); $nummer = 0; $pattern = join("|",@ARGV); while ($line = <INFO>) { if ($line !~ s/($pattern)/\($1\)/g) { print "$line \t"; next; } $nr = sprintf("%03d", ++$nummer); print "$nr $line"; }
Datum: 22.09.2005-11:28

|
re: @ARGV??? wie was wo und warum?
|
Seitenanfang |
Vielen Danke euch allen. Ihr habt mir sehr geholfen.So ein forum ist schon was feines ;-) Bis zum nächstenmal mfg Suchender
Datum: 22.09.2005-11:37

|
re: @ARGV??? wie was wo und warum?
|
Seitenanfang |
| kein Problem Falke ;) PS: hab mich jetzt hier mal gerregt^^
Datum: 22.09.2005-11:39

|
|

|

|

|
 |

|

|
|