Textdatei Datenbank Zeilenumbruch

  • (edit) dank Hinweis von Musashi ist es wohl besser, die Datenmenge mit SQLite zu bearbeiten.


    Hallo,

    ich habe eine Textdatei mit rund 2 Millionen Zeilen, die weiter unstrukturierten Text unterschiedlicher Länge erhalten wird.

    Diese Textdatei möchte ich nach mehreren Stichworten absatzweise mit AutoIt durchsuchen.

    1 Absatz mit einer x-beliebigen Anzahl von Zeilen, getrennt durch eine Leerzeile = 1 Datensatz

    Struktur

    Die Datensätze sind durch eine Leerzeile getrennt.

    Ich wollte die Daten mit StringSplit in ein Array umwandeln.

    Was nehme ich als Trennzeichen, um eine Leerzeile zu erkennen?

    Folgendes geht nicht mit StringSplit, klar, hat jede Zeile.

    @CRLF

    @CR

    @LF

    Mit StringInString wollte ich dann jeden Datensatz nach mehreren Stichworten durchsuchen, ob diese vorhanden sind und die Fundstellen (kompletter Absatz) ausgeben.

    Wie würdet Ihr das lösen?

    Schritt 1 - wie bekomme ich die Textdatei in ein Array, wenn eine Leerzeile das Trennzeichen ist?

    Einmal editiert, zuletzt von Banana_2_Day (2. August 2021 um 20:44)

  • Was ist eine Leerzeile?

    @CRLF@CRLF

    Beachte die Parameter bei Stringsplit, dann kannst du daran splitten.

    Badly formated variable or macro.:

    $trenn = @CRLF@CRLF

    $trenn = @CRLF & @CRLF

    das funktioniert

    Problem 1

    Testdatei ist ca. 300 MB groß

    ... teste ... melde mich in Kürze und formuliere dann die weiteren Fragen ...

    Einmal editiert, zuletzt von Banana_2_Day (2. August 2021 um 19:49)

  • Was ist damit ? :

    AutoIt
    #include <Array.au3>
    #include <StringConstants.au3>
    Global $aDataArr, $sDataStr
    $sDataStr = FileRead(@ScriptDir & "\DataListe.txt")
    $aDataArr = StringSplit($sDataStr, @CRLF & @CRLF, BitOR($STR_ENTIRESPLIT, $STR_NOCOUNT))
    _ArrayDisplay($aDataArr, "Array :")

    86598-musashi-c64-png

    "Am Anfang wurde das Universum erschaffen. Das machte viele Leute sehr wütend und wurde allenthalben als Schritt in die falsche Richtung angesehen."

  • Hier, zum Testen, noch mal mit direkt besetzten Daten (also kein FileRead) :

    86598-musashi-c64-png

    "Am Anfang wurde das Universum erschaffen. Das machte viele Leute sehr wütend und wurde allenthalben als Schritt in die falsche Richtung angesehen."

  • Nachtrag - Frage :

    Wäre es bei dieser Datenmenge nicht ggf. sinnvoll, eine Umsetzung mit SQLite zu überlegen ?

    86598-musashi-c64-png

    "Am Anfang wurde das Universum erschaffen. Das machte viele Leute sehr wütend und wurde allenthalben als Schritt in die falsche Richtung angesehen."

  • Danke Musashi, ich scheitere an folgenden Punkten:

    "Wäre es bei dieser Datenmenge nicht ggf. sinnvoll, eine Umsetzung mit SQLite zu überlegen ?"

    Ich vermute, SQLite ist eine Möglichkeit mit AutoIt, die ich nicht kenne?!

    Da muss ich mich einlesen.

    Ich habe auch schon überlegt, ob es ein alternatives Programm gibt.

    Die Datenmenge besteht aus vielen Zeilen und einer Leerzeile als Trenner.

    Ich kenne keine Programme, die das sinnvoll verarbeiten.


    Testdatei 300 MB mit 10116866 Zeilen, wird in Notepad plus in null komma nichts geöffnet.

    Habe auch UltraEdit und andere probiert.

    In keinem Programm kann ich die Suche auf Absätze eingrenzen. Daher die Idee, etwas mit AutoIt umzusetzen.

    Scheinbar klappt auch das Einlesen in ein Array in AutoIt gut.

    Das rekursive Löschen von Leerzeilen in einem großen Array dauert ewig mit:

    Oder gibt es eine schnelle Möglichkeit, x untereinander stehende Leerzeilen als 1 Leerzeile = 1 Trenner zu nehmen? Siehe Beispiel Post 1, die Anzahl der Leerzeilen ist unterschiedlich.

    For $i = UBound ( $aText ) - 1 To 0 Step -1

    If $aText[$i] = "" Then

    _ArrayDelete ( $aText , $i )

    EndIf

    Next

    Gibt es dafür eine schnellere Variante?


    kurze Zwischenmeldung - teste weiter -

  • Nachtrag - Frage :

    Wäre es bei dieser Datenmenge nicht ggf. sinnvoll, eine Umsetzung mit SQLite zu überlegen ?

    Klares Ja :)

    Hast Du ein Beispiel, wie ich obige Datenmenge in eine SQL-Datenbank überführe?

    Ich lese mir parallel in SQL ein.

    Wenn ich im Forum nach SQLite im Titel suche, sind die letzten Artikel aus 2018 und dann noch 1 - 2 ...

    Scheint ein seltenes Thema in aktueller Zeit zu sein.

    Das klingt schon mal hoffnungsvoll

    BugFix
    23. April 2018 um 11:41

    Einmal editiert, zuletzt von Banana_2_Day (2. August 2021 um 20:54)

  • Die Frage ob eine Datenbank wie SQLite hier sinnvoll wäre oder nicht können wir anhand des gezeigten gar nicht beurteilen.
    Für eine Datenbank müssen die Datensätze eine in sich wohnende feste Struktur haben.

    Das gezeigte Beispiel ist jedoch mal wieder herrlich unkonkret was komplett verhindert ableiten zu können wie man mit diesen Daten am besten umgeht.
    Da stehen nur durchnummerierte Datensatz-Header mit darauf folgenden variablen Anzahl an Textzeilen.
    Die Frage ist doch aber gibt es dort irgendeine inhaltliche Struktur? Gibt es dort eventuell bestimmte Attribute die jeden Datensatz beschreiben?

    Mit solchen nonsens-Beispielen kann man schlicht nicht adäquat Hinweise geben wie man damit umgeht.

    Zu deinem _ArrayDelete: Ja ist langsam weil bei einem einzelnen ArrayDelete alle Elemente die danach kommen einzeln nach vorne im Array verschoben werden müssen.
    Das dauert.
    Eventuell kann man versuchen mehrere Löschungen in einen Durchlauf unterzubringen so dass man nur einen Durchlauf braucht.
    Aber auch hier: Bitte ganz konkret am tatsächlichen Sachverhalt.

    Edit: Mal als ganz unkonkretes Beispiel wie ich das mit dem Delete in einem Durchlauf meinte:

    Einmal editiert, zuletzt von AspirinJunkie (2. August 2021 um 21:17)

  • Die Frage ob eine Datenbank wie SQLite hier sinnvoll wäre oder nicht können wir anhand des gezeigten gar nicht beurteilen.

    Die Frage ist doch aber gibt es dort irgendeine inhaltliche Struktur?

    Gibt es dort eventuell bestimmte Attribute die jeden Datensatz beschreiben?

    Ich versuche es zu konkretisieren.

    Trennzeichen ist eine oder mehrere Leerzeilen.

    Es ist eine immense Textsammlung. Damit vergleichbar, als ob jemand aus dem AutoIt Forum diverse Textpassagen zu unterschiedlichen Themen ohne Leerzeilen in eine Textdatei kopiert hat.

    Es sind aus News, Foren, Ideen zusammenkopierte Texte, ohne weitere Struktur. Beispiel unten. Wird Zeit für Ordnung :)

    Immer, wenn neuer Datensatz eingefügt wurde, wurde zuvor eine Leerzeile als Trenner hinzugefügt.

    Das ist die echte Datenmenge, die mir hier so vorliegt.

    Daher sieht die Struktur der Datenbank wirkich so aus, wie in Post 1 dargestellt. Die Header sind nur zur Verdeutlichung, die gibt es nicht.

    Textblock unterschiedlich lang

    eine oder mehrere Leerzeilen

    Textblock unterschiedlich lang

    eine oder mehrere Leerzeilen

    ...

    Da ich keine Möglichkeit kenne, bei einer Suche jeden Absatz als 1 Datensatz zu betrachten, wollte ich das in ein durchsuchbares Datenbankformat umwandeln.

    Ich hätte neben AutoIt auch z.B. die Möglichkeit auf Access zuzugreifen, aber keine Erfahrungen. Früher gab es noch Asksam, vielleicht kennt das jemand, eine Freitextdatenbank.

    In Schritt 1 möchte ich eine praktikable Möglichkeit, was ich mit der Datenmenge tun kann, um sie absatzweise durchsuchbar zu machen.

    Ich suche dabei 1 bis 12 Suchbegriffe, die in jedem Absatz = Datensatz vorkommen müssen.

    Diese Absätze sollen ausgegeben und im Original gelöscht werden.

    So wird aus dem Chaos eine neue Datenbank, die unter Stichworten verschlagwortet ist.

    Würde ich im untenstehenden Beispiel nach

    SQLite, Möglichkeit

    suchen, würde Datensatz = Absatz (4) zurückgegeben, im Original gelöscht und in eine neue Datenbank eingefügt werden.

  • Wenn ich im Forum nach SQLite im Titel suche, sind die letzten Artikel aus 2018 und dann noch 1 - 2 ...

    Scheint ein seltenes Thema in aktueller Zeit zu sein.

    Dazu nur mal ein Auszug aus https://de.wikipedia.org/wiki/SQLite

    Zitat

    SQLite ist eine gemeinfreie Programmbibliothek, die ein relationales Datenbanksystem enthält. SQLite wird in Mobiltelefonen (Android, iOS, Symbian OS, Windows Phone), in Browsern (Firefox, Safari, Chrome), Skype und vielen anderen Anwendungen eingesetzt. Es ist das verbreitetste und meistverwendete Datenbanksystem der Welt. SQLite unterstützt einen Großteil der im SQL-92-Standard

    SQLite wird von AutoIt gut unterstützt. Es wäre also keine verschwendete Zeit, sich damit auseinanderzusetzen :) .

    Scheinbar klappt auch das Einlesen in ein Array in AutoIt gut.

    Du meinst sicher 'anscheinend' (nicht 'scheinbar') :P .

    Mehr als das Einlesen der Daten in ein Array sollte mein Beispiel auch nicht verdeutlichen.

    Was die weiteren Aspekte Deines Projektes angeht, muss ich AspirinJunkie recht geben.

    Die von Dir gemachten Vorgaben sind zu 'unscharf' um konkrete Aussagen zu treffen.

    Testdatei 300 MB mit 10116866 Zeilen, wird in Notepad plus in null komma nichts geöffnet.

    Auch AutoIt kann große (Text-)dateien zügig einlesen - dass wäre nicht das Problem.

    Zeitintensiv und komplex wird es wahrscheinlich werden, wenn Du z.B. Absätze nach diversen Mustern durchsuchen willst usw.

    86598-musashi-c64-png

    "Am Anfang wurde das Universum erschaffen. Das machte viele Leute sehr wütend und wurde allenthalben als Schritt in die falsche Richtung angesehen."

  • Die von Dir gemachten Vorgaben sind zu 'unscharf' um konkrete Aussagen zu treffen.

    Konnte mein Beitrag in Post 10 mehr Klarheit bringen?

    Mein Datenmengen-Beispiel in Post 10 zeigt ein gutes Abbild von 4 Datensätzen.

    Habe sie mit in meine Datenbank eingefügt.

    Fragt bitte konkret, wenn die Beschreibung noch nicht ausreichend ist.

    Einmal editiert, zuletzt von Banana_2_Day (2. August 2021 um 22:24)

  • Konnte mein Beitrag in Post 10 mehr Klarheit bringen?

    Ja, etwas ;) . Wie so häufig bei Diskussionen mit kurzen Antwortintervallen haben sich unsere Beiträge überschnitten.

    Was Du gemacht hast, kenne ich (allerdings nicht in diesem Ausmaß).

    Wenn ich z.B. zu einem Thema recherchiere, dann sieht die erste Fassung meist auch so aus, dass ich alle Fundstellen in einer Textdatei ablege (Texte + ggf. Links usw.). Reine Linksammlungen habe ich mir schon lange abgewöhnt, da viele davon nach geraumer Zeit zunehmend ins Leere laufen. Die Texte selbst sind in dieser Phase nicht auf Schönheit ausgelegt, sondern es werden auch Satzfragmente zusammenkopiert und z.T. mit eigenen Kommentaren versehen, also quasi alles, was irgendwie passen könnte. (Trennsequenz bei mir ist z.B. ; ##################### ).

    Da ich allerdings für jedes Thema eine eigene Textdatei anlege (mit dem Namenssuffix _raw.txt), sind diese selten größer als einige KB's. Na ja, so hat halt jeder seine eigene 'Technik'.

    Du machst das offenbar im ganz großen Stil und zudem themenübergreifend, sonst wäre Deine Datei wohl kaum 300+ MB groß ^^ .

    So wie ich Deinen Aufbau verstanden habe, gibt es, kurz gesagt, also :

    -> 1..n Textblöcke unterschiedlicher Länge (innerhalb eines Blockes kommen keine Leerzeilen vor)

    -> die einzelnen Textblöcke werden durch 1..n Leerzeilen voneinander getrennt

    Ist das soweit richtig ?

    86598-musashi-c64-png

    "Am Anfang wurde das Universum erschaffen. Das machte viele Leute sehr wütend und wurde allenthalben als Schritt in die falsche Richtung angesehen."

  • Was Du gemacht hast, kenne ich (allerdings nicht in diesem Ausmaß).

    Das bedurfte jahrelanger Pflege :) und inzwischen hat das Ausmaß ein Volumen erreicht, dass ich die Reißleine und eine Lösung finden muss.

    "themenübergreifend" Ein gutes Stichwort – es landet vieles in einer einzigen Datei, es gibt mehr Infos als Zeit zur Verarbeitung.

    So wie ich Deinen Aufbau verstanden habe, gibt es, kurz gesagt, also :

    -> 1..n Textblöcke unterschiedlicher Länge (innerhalb eines Blockes kommen keine Leerzeilen vor)

    -> die einzelnen Textblöcke werden durch 1..n Leerzeilen voneinander getrennt

    Ist das soweit richtig ?

    Ja, genau so ist :)

  • Das Problem hatte ich auch vor Jahren - eine "digitale Zettelwirtschaft" mit allen möglichen Infos, die ich durchsuchen wollte.

    Ich habe mich damals entschieden, alles in eine MediaWiki zu überführen. Ich denke, das könnte auch das richtige für Dich sein.

  • Um eines gleich vorweg zu sagen (auch für andere User) :

    Für den Aufbau einer Knowledge-Base (ggf. sogar teamweit) ist das von mir verwendete Verfahren, nennen wir es wohlwollend, eher ungeeignet. Da ich die Ergebnisse der jeweiligen Recherchen aber themenbezogen in separate, und vom Umfang her überschaubare Textdateien mit aussagekräftigen Namen packe, komme ich gut damit klar. Falls ich doch mal etwas suchen muss -> Agent Ransack und fertig ! (alles etwas antiquiert, aber das bin ich mittlerweile auch ;) ).

    Banana_2_Day :

    Dir würde ein Textcrawler nur bedingt helfen, da Du alles in einer Riesendatei stehen hast.

    (ein) grober Ansatz :

    SQLite stellt einen Datentyp (genauer eine Storage Class) text bereit. Das ist ein Container, um beliebig langen Text zu speichern. Hier könntest Du je Textblock einen Datensatz anlegen. Die Suche nach 1..n Stichworten per SQL-Befehl liefert Dir dann eine Liste von Datensätzen, die die Bedingung erfüllen.

    Sorry, aber für heute muss ich jetzt Schluss machen.

    86598-musashi-c64-png

    "Am Anfang wurde das Universum erschaffen. Das machte viele Leute sehr wütend und wurde allenthalben als Schritt in die falsche Richtung angesehen."

  • Nachtrag :

    Daher sieht die Struktur der Datenbank wirkich so aus, wie in Post 1 dargestellt. Die Header sind nur zur Verdeutlichung, die gibt es nicht. Aufbau :

    Textblock unterschiedlich lang , eine oder mehrere Leerzeilen , Textblock unterschiedlich lang [...]

    Ein wesentlicher Schritt besteht ja darin, die Textblöcke voneinander zu separieren (egal, ob Du sie anschließend in einem Array oder als Datensätze in einer DB ablegst.

    Das kleine Demoskript aus Beitrag #5 ging davon aus, das es jeweils nur eine Leerzeile gibt.

    Bei mehreren Leerzeilen würde StringSplit($sDataStr, @CRLF & @CRLF, $STR_ENTIRESPLIT) zu leeren Elementen im Array führen.

    Daher sollten diese herausgefiltert werden, z.B. :

    86598-musashi-c64-png

    "Am Anfang wurde das Universum erschaffen. Das machte viele Leute sehr wütend und wurde allenthalben als Schritt in die falsche Richtung angesehen."