perlunity.de - PERL | JAVASCRIPT | PHP | MySQL | APACHE



#!/COMMUNITY

Members: 5374
davon online: 1
weitere User: 33
Click for quality!




10.02.2012 / 09:14

Community-Member werden   |   Paßwort vergessen   |   OnlineMonitor (1) Wer ist online ... OnlineMonitor starten !
     

 

Home


PERLscripts


PHPscripts


JAVAscripts


Hilfreiches


Links2www


Newscenter


Community


Interna




Community  »  Perl: Allgemeines Forum zur Themenübersicht Themensuche Themenansicht in Thread-Modus


Beitrag@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

Beitragre: @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

Beitragre: @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

Beitragre: @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

Beitragre: @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

Beitragre: @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

Beitragre: @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

Beitragre: @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

Beitragre: @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

Beitragre: @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

Beitragre: @ARGV??? wie was wo und warum?
Seitenanfang
kein Problem Falke ;)

PS: hab mich jetzt hier mal gerregt^^

Datum: 22.09.2005-11:39

-






-
-