• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

wo perl-script ablegen - etwa in perl /usr/local/bin/

lin

Hacker
Hi Community,


bin relativ neu bei Linux und auch neu bei Perl: Also sorry - jetzt kommen ein paar Newcomer-fragen: wo muss ich die perl-scripte auf einem OpenSuse 11.3 ablegen?

in:
perl /usr/local/bin/testscript.pl

BtW man kann auch das Modul CPAN:FindBin benutzen: Code (perl):
Code:
#!/usr/bin/perl
use strict;
use warnings;
use FindBin qw($Bin);

my $filename='./test.txt';

my $real_filename="$Bin/$filename";
open(my $fh, '<', $real_filename) || die("ERROR open $real_filename ($!)\n");
while(my $line=<$fh>)
{
  print $line;
}
close($fh);


Hmm - nun funktioniert das öffnen der Datei immer egal von wo aus man das Script startest. Im Script wird der relative Pfad um den absoluten vom Script ergänzt. Will man das aber plattformübergreifend korrekt mach so muss man das Modul CPAN:File::Spec benutzen. Das kann die verschiedenen Pfadtrenner handhaben.


Freue mich auf Tipps.

Grüße
Lin :/
 

}-Tux-{

Hacker
Hmm kommt drauf an, was dein Script genau macht - perl Module werden z.B. nach /usr/lib/perl5/* gepackaged (in openSUSE). Irgendwie verstehe ich das Problem/die Frage nicht so richtig.


}-Tux-{
 
OP
L

lin

Hacker
hi tux


danke für deine schnelle Antwort.

}-Tux-{ schrieb:
Hmm kommt drauf an, was dein Script genau macht - perl Module werden z.B. nach /usr/lib/perl5/* gepackaged (in openSUSE). Irgendwie verstehe ich das Problem/die Frage nicht so richtig.

}-Tux-{

Hab eine sammlung von HTML-Files in einem Ordner drinne. Die sollen geparst werden - um einen Auszug daraus zu kriegen. Einen kleinen Datensatz aus jedem der HTML-Files. Die HTML-Files sind im Grund alle in derselben Weise aufgebaut.

Also - die sollen geparst werden - und die Ergebnisse sollen in eine einzige neue Datei geschrieben werden. Das ist das was ich erreichen will.

Dieses Stück Code ist das was ich bis jetzt habe. Ich will es jetzt mal testen. Auf einer OpenSuse 11.3. Muss da wohl noch die Pfade anpassen - und z.B. meinen Ordner in dem die
HTML-Files (die zu parsen sind dann doch wohl school.html nennen - oder!?

Darüber hinaus - muss ich denn diesen Ordner in das selbe VErzeichnis wie das Script packen..!? DAS vielleicht nicht - aber ich muss wohl dafür sorgen, dass die PFade alle stimmen.

Wie würdest Du denn vorgehen, Tux!?

Gruß
lin :/

Code:
#!/usr/bin/perl
use strict;
use warnings;

use HTML::TokeParser;

my $file = 'school.html';
my $p = HTML::TokeParser->new($file) or die "Can't open: $!";

my %school;
while (my $tag = $p->get_tag('div', '/html')) {
        # first move to the right div that contains the information
        last if $tag->[0] eq '/html';
        next unless exists $tag->[1]{'id'} and $tag->[1]{'id'} eq 'inhalt_large';
        
        $p->get_tag('h1');
        $school{'location'} = $p->get_text('/h1');
        
        while (my $tag = $p->get_tag('div')) {
                last if exists $tag->[1]{'id'} and $tag->[1]{'id'} eq 'fusszeile';
                
                # get the school name from the heading
                next unless exists $tag->[1]{'class'} and $tag->[1]{'class'} eq 'fm_linkeSpalte';
                $p->get_tag('h2');
                $school{'name'} = $p->get_text('/h2');
                
                # verify format for school type
                $tag = $p->get_tag('span');
                unless (exists $tag->[1]{'class'} and $tag->[1]{'class'} eq 'schulart_text') {
                        warn "unexpected format: parsing stopped";
                        last;
                }
                $school{'type'} = $p->get_text('/span');
                
                # verify format for address
                $tag = $p->get_tag('p');
                unless (exists $tag->[1]{'class'} and $tag->[1]{'class'} eq 'einzel_text') {
                        warn "unexpected format: parsing stopped";
                        last;
                }
                $school{'address'} = clean_address($p->get_text('/p'));
                
                # find the description
                $tag = $p->get_tag('p');
                $school{'description'} = $p->get_text('/p');
        }
}

print qq/$school{'name'}\n/;
print qq/$school{'location'}\n/;
print qq/$school{'type'}\n/;

foreach (@{$school{'address'}}) {
        print "$_\n";
}

print qq/\nDescription: $school{'description'}\n/;

sub clean_address {
        my $text = shift;
        my @lines = split "\n", $text;
        foreach (@lines) {
                s/^\s+//;
                s/\s+$//;
        }
        return \@lines;
}

Muss ich da noch was anpassen - die Pfade oder!?
 

spoensche

Moderator
Teammitglied
Du musst den Pfad angeben, wo sich deine school.html befindet und das Gleiche gilt für die Datei, die du erzeugen möchtest.
 
OP
L

lin

Hacker
Guten Abend Spoensche!

vielen Dank für deine Mail und die Hinweise.

spoensche schrieb:
Du musst den Pfad angeben, wo sich deine school.html befindet und das Gleiche gilt für die Datei, die du erzeugen möchtest.

also, ich würde das Ganze dann doch einfach nach

usr/bin/ legen


Das Perlscript und die Datei shool.html - mit den HTML-Files die ich parsen will.
Die Datein die ich erzeugen will soll auch da rein.


Mal allgemein nachgefragt: also du meinst, dass ich das so machen soll:

Code:
# Verzeichnis in dem die HTML-Dateien gespeichert sind
my $school.html = '/path/to/dir/with/html.files';

# hole alle .html-Dateien aus dem Verzeichnis
my @school.html = File::Find::Rule->file->name( '*.html' )->in( $school.html );

Spoensche, ist das so okay!?

Das Auffinden würde ja...auf einer Windowsmaschine etwa so aussehhen:

Code:
my $html_dir="C:\htmlperl";
my $output="C:\htmlperl\output.txt";
my $file = $ARGV[0];


...wenn ich das auf OpenSuse machen, würde ich alles - wie oben geschildert am allerliebsten in usr/bin/ legen

Wie geht das mit dem Ausgeben? Kannst du mir da noch einen Tipp geben... Wie soll ich das nennen!?

Freu mich wieder von dir zu hoeren.


Gruß
Lin
 

}-Tux-{

Hacker
Warum willst du unbedingt "feste" Pfade verwenden? Wenn ueberhaupt solltest du nur
das Script selbst nach /usr/bin legen und nicht die Input-, sowie Outputfiles. Wenn du
es "portable" sein soll, benutze einfach Options fuer dein Script, die du beim Start
angibst, z.B. "script.pl --inputfiles /pfad/zu/den/inputfiles --output /pfad/zum/outputdir".


}-Tux-{
 
OP
L

lin

Hacker
Hallo Tux

vielen Dank für deine schnelle Antwort.

}-Tux-{ schrieb:
Warum willst du unbedingt "feste" Pfade verwenden? Wenn ueberhaupt solltest du nur
das Script selbst nach /usr/bin legen und nicht die Input-, sowie Outputfiles. Wenn du
es "portable" sein soll, benutze einfach Options fuer dein Script, die du beim Start
angibst, z.B. "script.pl --inputfiles /pfad/zu/den/inputfiles --output /pfad/zum/outputdir".

}-Tux-{

Danke - aber ich als Anfänger hab wohl am meisten davon wenn ichs am Anfang fest verdrahte.

Der Einfachheit halber FEST VERDRAHTET - am Anfang würd ich das ganze fest verdrahten...:

Also - ich bin dafür dass ich die Anfangssachen so überschaubar halte und das alles am Anfang lieber erstmal fest verdrahte!
d.h. also mit festen Pfaden arbeite - und dann ggf. alles in einen Ordner lege... Alle Files.
- a. das ausführende Programm
- b. die Datei mit den HTML-Files drinne
- c. die zu erzeugende Datei - in der die Resultate geschrieben werden.

So halte ich das am Anfang überschaubar. was meinste denn!? Wie sieht das denn fest "verdrahtet" aus?

viele

Grüße
lin :/
 
OP
L

lin

Hacker
hallo alle!


Hab eine sammlung von HTML-Files in einem Ordner drinne. Die sollen geparst werden - um einen Auszug daraus zu kriegen. Einen kleinen Datensatz aus jedem der HTML-Files.
Die HTML-Files sind im Grund alle in derselben Weise aufgebaut. Also - die sollen geparst werden - und die Ergebnisse sollen in eine einzige neue Datei geschrieben werden.
Das ist das was ich erreichen will.

Dieses o.g Stück Code ist das was ich bis jetzt habe. Ich will es jetzt mal testen. Auf einer OpenSuse 11.3. Muss da wohl noch die Pfade anpassen - und z.B. meinen Ordner in dem die
HTML-Files (die zu parsen sind dann doch wohl school.html nennen - oder!?
Darüber hinaus - muss ich denn diesen Ordner in das selbe Verzeichnis wie das Script packen..!? DAS vielleicht nicht - aber ich muss wohl dafür sorgen, dass die PFade alle stimmen.

Update: ich habe mal zwei Perl-Scripte genommen und geschaut ob ich denn die Files finden kann:

perl_script_two:

Code:
#!/usr/bin/perl

use strict;
use warnings;
use diagnostics;
use File::Find::Rule;

my @files = File::Find::Rule->file()
                 ->name('*.html')
                 ->in( 'home/usr/perl/html.files' );
foreach my $file(@files) {
        print $file, "\n";
}



response:


suse-linux:/usr/perl # perl perl_script_two.pl
Can't stat home/usr/html.files: No such file or directory at /usr/lib/perl5/site_perl/5.12.1/File/Find/Rule.pm line 594
suse-linux:/usr/perl #



und perl_script_three

Code:
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;
use File::Find::Rule;

my $HOME ="home/usr/perl/html.files";
opendir (THISDIR, $HOME) or warn "Could not open the dir ".$HOME.": $!";
@allfiles = grep !/^\.\.?$/, readdir THISDIR;
closedir THISDIR;

response: suse-linux:/usr/perl # perl perl_script_three.pl
Global symbol "@allfiles" requires explicit package name at perl_script_three.pl line 10.
Execution of perl_script_three.pl aborted due to compilation errors (#1)
(F) You've said "use strict" or "use strict vars", which indicates
that all variables must either be lexically scoped (using "my" or "state"),
declared beforehand using "our", or explicitly qualified to say
which package the global variable is in (using "::").

Uncaught exception from user code: Global symbol "@allfiles" requires explicit package name at perl_script_three.pl line 10. Execution of perl_script_three.pl aborted due to compilation errors. at perl_script_three.pl line 12 suse-linux:/usr/perl #

Hmm - ich bin etwas ratlos.

Freu mich auf einen Hinweis....

lin
 
OP
L

lin

Hacker
ich habe nochmlas nachgeacht


Mir ist aber noch ein weiterer Fehler aufgefallen: Ein Fehler bezüglich der HTML-Files die in dem Ordner (der Directory) htmlfiles drinne sind:
Es sind mehrere tausend Html files in der Directory drinne, die ich
mal html.files genannt habe - aber jetzt doch besser htmlfiles nenne.


Das folgende Schema ist da in dieser Directory erkennbar:

einzelergebnis1....html
einzelergebnis2...html
einzelergebnis3a...html
einzelergebnis3b...html
einzelergebnis3d...html


und so weiter; Also im Moment ist meine Frage die. Wie - u. nach welcher Konvention muss ich denn diese Zeile hier nennen.. oder sie tippen;


->name('*.einzel')

also entweder so:

-> name('*.einzel')

oder so -> name('einzel*.')

Frage mich das deshlab weil ich glaube dass Perl meine Files gar nicht finden kann wenn ich das falsch mache - wenn ich hier nicht sehr korrekt bin.


Code:
#!/usr/bin/perl

use strict;
use warnings;
use diagnostics;
use File::Find::Rule;

my @files = File::Find::Rule->file()
                 ->name('*.einzel')
                 ->in( '/home/usr/htmlfiles' );
foreach my $file(@files) {
        print $file, "\n";
}


Freu mich hier in der FRAGE weiterzukommen.

Wenn ich diese Frage genauer stellen muss dann sagt einfach Bescheid.

Freu mich - das dann näher erklären zu koennen.



Die Feinarbeit kann ich später noch machen...

Grüße
lin
 
OP
L

lin

Hacker
hallo Community!


also nach einiger Verwirrung bin ich jetzt doch etwas weiter gekommen:

ich habe folgendes gewechselt:

Code:
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;
use File::Find::Rule;
my @files = File::Find::Rule->file()
                 ->name('einzelergebnis*.html')
                 ->in( '/home/usr/perl/htmlfiles' );
foreach my $file(@files) {
        print $file, "\n";

}

Code:
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;
use File::Find::Rule;
my @files = File::Find::Rule->file()
                 ->name('einzelergebnis*.html')
                 ->in( '.' );
foreach my $file(@files) {
        print $file, "\n";

}

Dann habe ich folgenden Output gekriegt:

htmlfiles/einzelergebnis80b5.html
htmlfiles/einzelergebnisa0ef.html
htmlfiles/einzelergebnis1b42.html
htmlfiles/einzelergebnis5960.html
htmlfiles/einzelergebnise523.html
htmlfiles/einzelergebnis2c7e.html
htmlfiles/einzelergebnisdf57.html
htmlfiles/einzelergebnis2b53-2.html
htmlfiles/einzelergebnisb1c0-2.html
htmlfiles/einzelergebnis8e8b.html
htmlfiles/einzelergebnisdcc1.html
htmlfiles/einzelergebnis1dae-2.html
htmlfiles/einzelergebnisa70d.html
htmlfiles/einzelergebnis3cec.html
htmlfiles/einzelergebnis3f1f.html
htmlfiles/einzelergebnis1d2b.html
htmlfiles/einzelergebnis396c.html
htmlfiles/einzelergebnis2592.html
htmlfiles/einzelergebnisdee0.html
htmlfiles/einzelergebnis987b-2.html
htmlfiles/einzelergebnise20b.html
htmlfiles/einzelergebnised05.html
htmlfiles/einzelergebnisdec3.html

and 22 tausend weitere Zeilen... ;-)

Greetz lin! :/

Jetzt gehts daran das oben gelernte zu übertragen auf das folgende Script:


Code:
#!/usr/bin/perl
use strict;
use warnings;

use HTML::TokeParser;

my $file = 'school.html';
my $p = HTML::TokeParser->new($file) or die "Can't open: $!";

my %school;
while (my $tag = $p->get_tag('div', '/html')) {
	# first move to the right div that contains the information
	last if $tag->[0] eq '/html';
	next unless exists $tag->[1]{'id'} and $tag->[1]{'id'} eq 'inhalt_large';
	
	$p->get_tag('h1');
	$school{'location'} = $p->get_text('/h1');
	
	while (my $tag = $p->get_tag('div')) {
		last if exists $tag->[1]{'id'} and $tag->[1]{'id'} eq 'fusszeile';
		
		# get the school name from the heading
		next unless exists $tag->[1]{'class'} and $tag->[1]{'class'} eq 'fm_linkeSpalte';
		$p->get_tag('h2');
		$school{'name'} = $p->get_text('/h2');
		
		# verify format for school type
		$tag = $p->get_tag('span');
		unless (exists $tag->[1]{'class'} and $tag->[1]{'class'} eq 'schulart_text') {
			warn "unexpected format: parsing stopped";
			last;
		}
		$school{'type'} = $p->get_text('/span');
		
		# verify format for address
		$tag = $p->get_tag('p');
		unless (exists $tag->[1]{'class'} and $tag->[1]{'class'} eq 'einzel_text') {
			warn "unexpected format: parsing stopped";
			last;
		}
		$school{'address'} = clean_address($p->get_text('/p'));
		
		# find the description
		$tag = $p->get_tag('p');
		$school{'description'} = $p->get_text('/p');
	}
}

print qq/$school{'name'}\n/;
print qq/$school{'location'}\n/;
print qq/$school{'type'}\n/;

foreach (@{$school{'address'}}) {
	print "$_\n";
}

print qq/\nDescription: $school{'description'}\n/;

sub clean_address {
	my $text = shift;
	my @lines = split "\n", $text;
	foreach (@lines) {
		s/^\s+//;
		s/\s+$//;
	}
	return \@lines;
}
 
Oben