In Datei schreiben und zwar sortiert
Kahn
- perl
Hai.
habe erst vor 2 tagen mit perl angefangen und stehe jetzt schon vor einem problem aber für das finde ich keine antwort. eigentlich ist es kein problem sondern ich suche ein verbesserungsvorschlag zu dem.
ich habe eine liste mit bestimmten worten diese ist alphabetisch geordnet und jetzt will ich mit einem perl script wörter in die datei schreiben diese sollen aber geordnet reingeschrieben werden und das mögloichst unkompliziert denn mein jetziger weg sieht so aus:
1. Datei öffnen und wort hineinschreiben datei schliessen
2. Datei öffnen datei in ein array lesen das array sortieren datei schliessen
3. Datei öffnen alten inhalt überschreiben mit dem array datei schliessen
das kann man doch bestimmt optimiren oder?
ein kleiner hinweis: ich will dafür kein modul benutzen das ich extra runterladen müsste höchstens die module die bereits in der perl 5.8 oder 5.10 version dabei sind.
wäre nett wenn ihr mir helfen würdet.
lg
ich habe eine liste mit bestimmten worten diese ist alphabetisch geordnet und jetzt will ich mit einem perl script wörter in die datei schreiben diese sollen aber geordnet reingeschrieben werden und das mögloichst unkompliziert denn mein jetziger weg sieht so aus:
- Datei öffnen und wort hineinschreiben datei schliessen
- Datei öffnen datei in ein array lesen das array sortieren datei schliessen
- Datei öffnen alten inhalt überschreiben mit dem array datei schliessen
das kann man doch bestimmt optimiren oder?
Klar! Schritt 1 kannst du dir sparen, wenn du dein Wort an den Array pusht, bevor du den Array sortierst.
wäre nett wenn ihr mir helfen würdet.
Womit? Ich sehe keinen Code.
mfg Beat
hi.
danke erstmal für die zahlreichen antworten.
also der code sollte eigentlich klar sein aber hier nochmal:
#!/usr/bin/perl -w
use strict;
#Hier wird das Wort erstmal unsortiert in die vorhandene Liste eingefügt.
open (LISTE, ">>datei.txt");
print LISTE "Kuchen";
close (LISTE);
#Hier wird der Inhalt in sortierter reihenfolge in das array sort geschrieben
open (SORTIEREN, "<datei.txt");
my @sort = sort <SORTIEREN>;
close (SORTIEREN);
#Hier wird das sortierte array mit dem vorhandenen inhalt der datei ueberschrieben
open (NEU, ">datei.txt");
print NEU "@sort";
close (NEU);
exit;
habe mich informiert über push das klappt natürlich besser aber ich habe auf unzähligen seiten gelesen das man dateien direkt einlesen bzw. ändern sollte und auch hier hab ich gelesen das man vermeiden sollte die datei in ein array oder ähnliches zu schreiben. Kann ich natürlich verstehen wenn die datei mehrere MB gross wird.
würdet ihr das genauso machen wie ich bzw. die andere variante mit push?
habe mich informiert über push das klappt natürlich besser aber ich habe auf unzähligen seiten gelesen das man dateien direkt einlesen bzw. ändern sollte und auch hier hab ich gelesen das man vermeiden sollte die datei in ein array oder ähnliches zu schreiben. Kann ich natürlich verstehen wenn die datei mehrere MB gross wird.
würdet ihr das genauso machen wie ich bzw. die andere variante mit push?
Wenn Speicher die Limite ist, dann verwende Tie:File
Bei deinem Code macht es nämlich keinen Unterschied ob du sagst:
sort <Filehandle>
oder
sort @array
Tie:File ist ein Standard Modul.
mfg Beat
hi.
danke hab mich mal mit tie:file auseinander gesetzt hab aber leider keine hilfreiche hilfe dazu gefunden also zu meinem problem darum hab ich es so gemacht:
my @liste;
tie @liste, 'Tie::File', "datei.txt";
@liste = sort @liste;
untie @liste;
das klappt zwar wunderbar nur gibt es da ein problem: es werden einfach leerzeilen eingefügt. ich habe auch von perldoc von autochomp => 0 gelesen aber das bringt auch nichts.
was mach ich (schonw ieder) falsch?
lg
danke hab mich mal mit tie:file auseinander gesetzt hab aber leider keine hilfreiche hilfe dazu gefunden also zu meinem problem darum hab ich es so gemacht:
my @liste;
tie @liste, 'Tie::File', "datei.txt";
@liste = sort @liste;
untie @liste;das klappt zwar wunderbar nur gibt es da ein problem: es werden einfach leerzeilen eingefügt. ich habe auch von perldoc von autochomp => 0 gelesen aber das bringt auch nichts.
was mach ich (schonw ieder) falsch?
Das scheint sich um einen Bug in Perl zu handeln
http://www.perlmonks.org/?node_id=710580
"... it only occurs in the optimized case of a tied array where the sort is of this format:
@a = sort @a.
"
Der Workaround um den Bug ist, statt
@tied_array = sort @tied_array;
die Alternative
@tied_array = ((), sort @tied_array);
zu verwenden.
Der Bug überrascht mich. Allerdings pflege ich keine ganzen Files zu sortieren.
mfg Beat
das kann man doch bestimmt optimiren oder?
kommt drauf an, was du unter diesem zusammenhang unter optimieren verstehst. Die beste Optimierung bei solchen Fragestellungen, wäre eine Datenbank, aber mit diesem Anspruch scheitert das:
ein kleiner hinweis: ich will dafür kein modul benutzen das ich extra runterladen müsste höchstens die module die bereits in der perl 5.8 oder 5.10 version dabei sind.
Dann machst du etwas grundsätzliches falsch.
Für Perl sind die Module des CPAN fundamental, d.h. niemand der ernsthaft mit Perl arbeitet, sollte auf diese Module verzichten. Das ist wie bei den meisten anderen Programmiersprachen ohne Bibliotheken ist der Aufwand i.d.R. viel zu hoch. Sei es das du Datenbanken benutzen willst, grafische Oberflächen oder CGI Programme schreiben. Für alles gibt es getestete Module die sich bewährt haben.
Struppi.
ein kleiner hinweis: ich will dafür kein modul benutzen das ich extra runterladen müsste höchstens die module die bereits in der perl 5.8 oder 5.10 version dabei sind.
Dann machst du etwas grundsätzliches falsch.
Für Perl sind die Module des CPAN fundamental, d.h. niemand der ernsthaft mit Perl arbeitet, sollte auf diese Module verzichten. Das ist wie bei den meisten anderen Programmiersprachen ohne Bibliotheken ist der Aufwand i.d.R. viel zu hoch. Sei es das du Datenbanken benutzen willst, grafische Oberflächen oder CGI Programme schreiben. Für alles gibt es getestete Module die sich bewährt haben.Struppi.
Irgendwie höre ich einen leicht hysterischen Ton. Woher?
Klingt so, als ob man ohne Ferrari nie rechtzeitig in die Schule kommt.
mfg Beat
Irgendwie höre ich einen leicht hysterischen Ton. Woher?
Keine Ahnung, von mir nicht.
Klingt so, als ob man ohne Ferrari nie rechtzeitig in die Schule kommt.
Auf ein Auto-beispiel hatte ich verzichtet, da du ein Auto i.d.R. komplett bekommst, du musst es nur warten. Aber wenn du ein Auto baust verzichtest du wohl kaum auf externe Komponenten. Klar kannst du die Elektronik, die Sitze, die Stoßdämpder usw. selbst bauen, aber soweit ich weiß kaufen die meisten Autohersteller diese von externen Anbietern.
Struppi.
Irgendwie höre ich einen leicht hysterischen Ton. Woher?
Klingt so, als ob man ohne Ferrari nie rechtzeitig in die Schule kommt.mfg Beat
lol. ich hatte mal ein Perl-script geschrieben, was ansich tadellos funktionierte. Es konnste Bilder von www.imagevenue.com aus einer Linkliste heraus downloaden. Jedoch: Ich habe kein CPAN Modul benutzt. Nicht mal eines. Es war also nur ein Fahrrad und kein Ferrari. Das fanden die Perl-Mönche, denen ich es zeigte, nicht so toll. Sie bestehen auf dem Ferrari :)
Ansich ist es richtig, für ein Perlscript nach Möglichkeit CPAN Module zu verwenden. Für einen Anfänger aber ist es sehr hilfreich, wenn er zunächst mal alles händisch schreibt, und für zukünftige Sachen dann CPAN nutzt. Wenn er händisch programmiert lernt er ja auch ne Menge dabei.
Auch wenn die Perlmönche sauer werden :)
Irgendwie höre ich einen leicht hysterischen Ton. Woher?
Klingt so, als ob man ohne Ferrari nie rechtzeitig in die Schule kommt.mfg Beat
lol. ich hatte mal ein Perl-script geschrieben, was ansich tadellos funktionierte. Es konnste Bilder von www.imagevenue.com aus einer Linkliste heraus downloaden. Jedoch: Ich habe kein CPAN Modul benutzt. Nicht mal eines. Es war also nur ein Fahrrad und kein Ferrari. Das fanden die Perl-Mönche, denen ich es zeigte, nicht so toll. Sie bestehen auf dem Ferrari :)
Euer Bild ist falsch, du willst nicht ein Auto oder ein Fahrrad, sondern ein gekauftes Auto oder selbstgebautes Auto. Du baust dein Auto selbst, das ist bewunderswert, aber mühsam und teuer (von der Arbeitszeit).
Ansich ist es richtig, für ein Perlscript nach Möglichkeit CPAN Module zu verwenden. Für einen Anfänger aber ist es sehr hilfreich, wenn er zunächst mal alles händisch schreibt, und für zukünftige Sachen dann CPAN nutzt. Wenn er händisch programmiert lernt er ja auch ne Menge dabei.
Du lernst erstmal nicht viel. Ich weiß nicht ob du C oder etwas ähnliches programmieren kannst oder auch Java. den Kern der Sprache hast du schnell gelernt, for Schleifen if Bedingungen, Funktionen, Datentypen, das kann man schnell. aber ob du unbedingt Wissen musst welches Register für eine Tastatureingabe zuständig ist, weiß ich nicht. Wer Treiber entwickelt oder das maximale aus der Maschine rausholen muss, bestimmt. Aber solche Leute programmieren nicht in Perl.
Aber mit Modulen umzugehen, sie zu finden, installieren oder auch um daraus zu lernen, ist ein wichtige Sache. In anderen Programmiersprachen noch viel mehr als in Perl.
Auch wenn die Perlmönche sauer werden :)
Wenn du gerne mit einem selbgesbasteltem Auto fährst, ärgert sich keiner (höchstes der TÜV, den gibt es aber hier nicht), im gegenteil das ist verdient Respekt vor der Arbeit die du dir machst, aber nicht unbedingt klug.
Struppi.
lol. ich hatte mal ein Perl-script geschrieben, was ansich tadellos funktionierte. Es konnste Bilder von www.imagevenue.com aus einer Linkliste heraus downloaden. Jedoch: Ich habe kein CPAN Modul benutzt. Nicht mal eines.
Wobei - soweit ich dich hier erlebt habe, kan ich mir dass nicht vorstellen. Du hast ein Bild von einer anderen Seite geladen, ohne LPW::Simple (das widerrum auch nochmal drei Module benötigt)? oder hast du wget benutzt?
Wenn ich mich Irre: Respekt!
Statt eines Einzeilers, hast du eine umfangreiche, geprüfte, kostenlose Software in Teilen neu geschrieben.
Struppi.
Wobei - soweit ich dich hier erlebt habe, kan ich mir dass nicht vorstellen. Du hast ein Bild von einer anderen Seite geladen, ohne LPW::Simple (das widerrum auch nochmal drei Module benötigt)? oder hast du wget benutzt?
Wenn ich mich Irre: Respekt!
So ist es. Ohne LWP, ohne irgendwas. Ja, mit wget. Und es funtkionierte. Es las strings einfach aus einem Linkfile, sofern das Linkfile durchgängig korrekt war gabs auch keine Fehler. Es liegt sogar noch bei nopaste auf ubuntuusers.de, wenn Du mir nicht glaubst :)
Statt eines Einzeilers, hast du eine umfangreiche, geprüfte, kostenlose Software in Teilen neu geschrieben.
Ja das mag ja sein. Ich erhebe ja auch nicht den Anspruch ein Perlmeister zu sein. Es war eben ein schneller, funktionierender Hack mehr nicht.
Gruß
Wobei - soweit ich dich hier erlebt habe, kan ich mir dass nicht vorstellen. Du hast ein Bild von einer anderen Seite geladen, ohne LPW::Simple (das widerrum auch nochmal drei Module benötigt)? oder hast du wget benutzt?
Wenn ich mich Irre: Respekt!
So ist es. Ohne LWP, ohne irgendwas. Ja, mit wget.
Also mit einem externen Tool, das nur auf manchen Systemen zu Verfügung steht. LWP::Simple dürfte weiter verbreitet sein.
Es liegt sogar noch bei nopaste auf ubuntuusers.de, wenn Du mir nicht glaubst :)
Doch ich glaune dir. Meine Verwunderung rührte ja daher, dass ohne Modul für mich bedeutet hätte, dass du das Skript auch ohne ein externes Tool geschrieben hättest und den kompletten Netzwerkverkehr selbst mit Perl programmierst, was mich sehr verwundert hätte und was ich dir nicht zutraue.
Statt eines Einzeilers, hast du eine umfangreiche, geprüfte, kostenlose Software in Teilen neu geschrieben.
Ja das mag ja sein.
Nö, so ist es nicht, du hast ja nichts neu geschrieben. LWP::Simple ist quasi das Perl Modul, das die Funktionalität von wget ersetzt (und noch viel mehr kann). D.h. du hast nichts neu geschrieben sondern es ist
ein schneller, funktionierender Hack mehr nicht.
Ein Hack genau. Einer der das Skript aber nur Systemen lauffähig macht, wo wget installiert ist, was aber solange dir das ausreicht nichts verwerfliches ist, mit LWP::Simple wäre es aber einfacher, ohne Hack gewesen.
Struppi.
Ein Hack genau. Einer der das Skript aber nur Systemen lauffähig macht, wo wget installiert ist, was aber solange dir das ausreicht nichts verwerfliches ist, mit LWP::Simple wäre es aber einfacher, ohne Hack gewesen.
LWP: oder sonstige Module setzen aber voraus, daß eben diese Module beim Benutzer auch vorhanden sind? - Ist das denn der Fall für, sagen wir mal "handelsübliche" Perl Installationen/Konfigurationen für, sagen wir mal "handelsübliche" Linuxe? Sprich, für einen User der mit Perl nicht so Bescheid weiss, aber dieses Script gern nutzen möchte. Und wie siehts auf Win. oder Mac OS aus?
LWP: oder sonstige Module setzen aber voraus, daß eben diese Module beim Benutzer auch vorhanden sind? - Ist das denn der Fall für, sagen wir mal "handelsübliche" Perl Installationen/Konfigurationen für, sagen wir mal "handelsübliche" Linuxe? Sprich, für einen User der mit Perl nicht so Bescheid weiss, aber dieses Script gern nutzen möchte. Und wie siehts auf Win. oder Mac OS aus?
Sofern du dich an der Liste der core module für perl 5.8 orientierst, bist du auf der sicheren Seite.
http://perldoc.perl.org/5.8.8/index-modules-A.html
Ich habe in der Active State Installation einige Komponenten, die dort nicht eingetragen sind.
mfg Beat
Ein Hack genau. Einer der das Skript aber nur Systemen lauffähig macht, wo wget installiert ist, was aber solange dir das ausreicht nichts verwerfliches ist, mit LWP::Simple wäre es aber einfacher, ohne Hack gewesen.
LWP: oder sonstige Module setzen aber voraus, daß eben diese Module beim Benutzer auch vorhanden sind? - Ist das denn der Fall für, sagen wir mal "handelsübliche" Perl Installationen/Konfigurationen für, sagen wir mal "handelsübliche" Linuxe? Sprich, für einen User der mit Perl nicht so Bescheid weiss, aber dieses Script gern nutzen möchte. Und wie siehts auf Win. oder Mac OS aus?
Diese Frage hast du dir aber nicht gestellt, als du wget benutzt hast?
Wie schon Eingangs gesagt, Module sind ein fundamentaler Bestandteil von Perl, wenn du meinst ohne sie auszukommen, dann schreibst du keine Programme in Perl, sondern Hacks.
Struppi.
Hello,
- Datei öffnen und wort hineinschreiben datei schliessen
- Datei öffnen datei in ein array lesen das array sortieren datei schliessen
- Datei öffnen alten inhalt überschreiben mit dem array datei schliessen
das kann man doch bestimmt optimiren oder?
Das __muss__ man, unabhängig von der verwendeten Scriptsprache vermutlich verbessern.
Wenn die Applikation im Mehrbenutzerbetrieb genutzt wird, musst Du auch auf sogenannte Race Conditions, also auf das Laufzeitverhalten und Konkurrenzverhalten unterscheidlicher (Benutzer-)Prozesse achten.
Wenn Du speicherorientiert, also das Gegenteil von speicheroptimiert, arbeiten kannst, die Datei also vollständig in den Speicher passt, und Du trotzdem noch reichlich Speicher übrig hat, dann ist der Umgang mit den Arrays sicherlich der schnellste Weg, denn Jedes Verschieben von daten im Hauptspeicher ist etliche Male schneller, als ein Lesezugriff auf die Festplatte.
Dann muss die Datei aber __vor__ dem Einlesen bereits exclusiv für den gesamten Änderungsprozess gesperrt werden http://aktuell.de.selfhtml.org/artikel/programmiertechnik/dateisperren/
1. Dateihandle besorgen
2. Datei exclusiv sperren
Bei vernünftigen Betriebssystemen geht das in einem atomar gekapselten Schritt
Seit etlichen Jahren auch bei unixoiden.
Außerdem geht es bei diesen Systemen auch nur für betroffene Teile der Datei
2b. Dateilänge auslesen
3. Datei auslesen
4. Daten im Speicher sortieren, ändern, ergänzen, herauslöschen
5. Daten zurückschreiben in Datei
6. Dateilänge anpassen auf neue Länge, wenn kürzer als alte
7. Datei schließen und _nur__dadurch_ Sperrung freigeben
Die nächste Möglichkeit wäre eine direktgestreute Datei. Diese Möglichkeit ist aber trotz der heute gängingen Festplattengrößen im Allgemeinen immer noch nur eine theoretische Möglichkeit. Direktgestreut bedeutet, dass für jeden möglichen Eintrag ein Platz freigehalten wird im vorher allokierten Persistenen Speicherbereich. Bei UNIXen machte man das bereits beim Anlegen der Dateien, indem man die Anzahl der "Extents" (Ausdehnungen) der Datei festgelegt hat.
Außerdem muss der Wertebereich dafür ordinal sein. Es wäre also unsinnig , für Realzahlen eine direktgestreute Datei einzurichten. Sinnvoll wäre es aber für deutsche Autokennzeichen.
Nun kommt man über diese Überlegung direkt zur nächsgten Möglichkeit: Die Datei in einem Stück wird viel zu groß. So kann man dann filesystemorientiert arbeiten, und dessen Möglichkeiten nutzen. Man legt eine Struktur an, die für jedes mögliche Zeichen an erster Stelle ein Verzeichnis vorsieht.
Darin legt man dann eine Struktur an, die für jedes mögliche Zeichen an zweiter Stelle eine Datei vorsieht... Je nach erlaubtem Wertevorrat (ASCII-Auschnitt 42 Zeichen, 64 Zeichen, 96 Zeichen oder was Dir sonst so einfällt) muss eben ein Verzeichnis her.
Als Blatt in disen Knoten (Verzeichnissen und Unterverzeichnissen) stehen dann eine oder mehrere Dateien als Blätter. In den Blattdateien liegen dann Listen, die z.B. sortiert abgepeichert werden so wie im ersten Fall durchdacht.
NUn könnte jemand auf die Idee kommen, dass man diese gesamte Struktur wieder in eine Datei packt, um Dateihandles zu sparen (man spart während der Laufzeit aber nicht wirklich welche, bestenfalls 2). Für den geordneten Zugriff benötigt man spätestens jetzt ein Zugriffssystem, also ein DBMS. Bis eben konnte man die Arbeit noch bei ausreichender Disziplin mit einem passenden Texteditor erledigen.
Ich hoffe, dass Dir diese kleine philosophische bzw. rückblickende Betrachtung einige Anregungen gegeben hat, wie man Daten sortiert verwalten könnte...
Liebe Grüße aus Syburg bei Dortmund
Tom vom Berg