[gelöst] riesige Textdatei: einzelne (nicht unique) Zeile...
[gelöst] riesige Textdatei: einzelne (nicht unique) Zeile...
(war: "riesige Textdatei: einzelne (nicht unique) Zeile verändern")
Hallo,
ich habe hier eine Textdatei von gut 12GB Größe.
In dieser möchte ich gern eine einzelne Zeile (bzw. einen Teil davon) ändern. Das Problem ist, dass diese Zeile (nennen wir sie "A") schätzungsweise mehrere 100000 mal in der Textdatei vorkommt. Ich möchte aber nur ein ganz bestimmtes Vorkommen von A ändern (nennen wir es "A0"). Das Einzige was ich mit Sicherheit zum Finden von A0 sagen kann ist, dass es eine unique Zeile B gibt die sich irgendwo vor A0 befindet (vermutlich 10-100 Zeilen) und es zwischen B und A0 kein weiteres A gibt.
Ich habe versucht die Datei in vi zu öffnen, was speichermäßig dank 12GB RAM auch noch fast passt, aber wenn die ganze Datei nach einigen Minuten im Cache ist zeigt vi sie nicht an - bzw. braucht elendig lange dazu und lastet dabei einen Kern meiner CPU voll aus (ich habe es nach 2 Stunden abgebrochen). nano stellte sich nicht besser an und von GUI-Editoren verspreche ich mir auch nicht mehr. Ich habe leise Hoffnung, das ed mich vielleicht weiterbringen könnte, aber dazu müsste ich vermutlich nochmal bei Meillo die Schulbank drücken.
Mit sed weiß ich mir auf Anhieb auch nicht zu helfen, denn A ist ja nicht eindeutig und wie ich von B auf A0 schließen soll ohne die Datei mehrmals durchzulesen ist mir noch nicht eingefallen. Falls mir nichts anderes einfällt werde ich mir selbst ein Script stricken, das dann eben mehrfach durch die Datei geht, aber ich hoffe jemand hat einen schlauen Tipp wie ich mir das sparen kann.
Hallo,
ich habe hier eine Textdatei von gut 12GB Größe.
In dieser möchte ich gern eine einzelne Zeile (bzw. einen Teil davon) ändern. Das Problem ist, dass diese Zeile (nennen wir sie "A") schätzungsweise mehrere 100000 mal in der Textdatei vorkommt. Ich möchte aber nur ein ganz bestimmtes Vorkommen von A ändern (nennen wir es "A0"). Das Einzige was ich mit Sicherheit zum Finden von A0 sagen kann ist, dass es eine unique Zeile B gibt die sich irgendwo vor A0 befindet (vermutlich 10-100 Zeilen) und es zwischen B und A0 kein weiteres A gibt.
Ich habe versucht die Datei in vi zu öffnen, was speichermäßig dank 12GB RAM auch noch fast passt, aber wenn die ganze Datei nach einigen Minuten im Cache ist zeigt vi sie nicht an - bzw. braucht elendig lange dazu und lastet dabei einen Kern meiner CPU voll aus (ich habe es nach 2 Stunden abgebrochen). nano stellte sich nicht besser an und von GUI-Editoren verspreche ich mir auch nicht mehr. Ich habe leise Hoffnung, das ed mich vielleicht weiterbringen könnte, aber dazu müsste ich vermutlich nochmal bei Meillo die Schulbank drücken.
Mit sed weiß ich mir auf Anhieb auch nicht zu helfen, denn A ist ja nicht eindeutig und wie ich von B auf A0 schließen soll ohne die Datei mehrmals durchzulesen ist mir noch nicht eingefallen. Falls mir nichts anderes einfällt werde ich mir selbst ein Script stricken, das dann eben mehrfach durch die Datei geht, aber ich hoffe jemand hat einen schlauen Tipp wie ich mir das sparen kann.
Zuletzt geändert von hikaru am 03.02.2011 21:24:45, insgesamt 1-mal geändert.
Re: riesige Textdatei: einzelne (nicht unique) Zeile verände
hi,
wenn das ein einmaliges Abenteuer ist und man das "(vermutlich 10-100 Zeilen)" präzisieren kann:
liefert die entscheidende Zeilennummer, damit sollte man sed gezielt sagen können, was zu ändern ist. Die Datei wird also typischerweise 1.5 Mal gelesen.
Wenn das zur Gewohnheit werden soll: ein C-Programm. Wenn die Änderung die Länge der Datei nicht ändert, muss man nicht einmal eine Kopie erzeugen, man muss nur bis A0 lesen, kann mitten in die Datei schreiben und den Rest ignorieren.
wenn das ein einmaliges Abenteuer ist und man das "(vermutlich 10-100 Zeilen)" präzisieren kann:
Code: Alles auswählen
grep -A 101 -n --max-count=1 "B" datei | grep "A0"
Wenn das zur Gewohnheit werden soll: ein C-Programm. Wenn die Änderung die Länge der Datei nicht ändert, muss man nicht einmal eine Kopie erzeugen, man muss nur bis A0 lesen, kann mitten in die Datei schreiben und den Rest ignorieren.
Beware of programmers who carry screwdrivers.
Re: riesige Textdatei: einzelne (nicht unique) Zeile verände
Ich habe wohl gerade Tomaten auf den Augen. Womit gebe ich denn sed eine Zeilennummer mit?
Re: riesige Textdatei: einzelne (nicht unique) Zeile verände
das musste ja so kommen, jetzt hab' ich mich sowas 30 Jahre erfolgreich um sed-Lernen gedrückt...
Ach, übrigens darf jeder auf jeden Beitrag antworten...
Ach, übrigens darf jeder auf jeden Beitrag antworten...
Beware of programmers who carry screwdrivers.
Re: riesige Textdatei: einzelne (nicht unique) Zeile verände
Nur mal als Idee für ed:
Folgendes sollte die gesuchte A Zeile (+ Zeilennummer) nach B ausgeben:
Wenn das das gewünschte Ergebnis liefert, kann man darüber Nachdenken die Zeile zu ändern.
Folgendes sollte die gesuchte A Zeile (+ Zeilennummer) nach B ausgeben:
Code: Alles auswählen
$ ed -s test.txt << EOF
/B/
/A/
n
EOF
MfG GoKi
:wq
:wq
-
- Beiträge: 827
- Registriert: 26.05.2008 12:04:54
- Lizenz eigener Beiträge: GNU Free Documentation License
- Wohnort: Nörten-Hardenberg
-
Kontaktdaten:
Re: riesige Textdatei: einzelne (nicht unique) Zeile verände
Hallo,
könntest du mal ein längeres Testmuster per NoPaste oder als dl zur Verfügung stellen.
Würde gerne mal schauen was ich da tun könnte.
Ggf. würde ich mal wieder C/C++ ausgraben um damit mal ein kleines Testprogramm zu bauen was ggf. die Zeilennummer sucht und die Zeile ausgibt.
Ich bräuchte nur zu wissen wie Zeile B komplett lautet und wie ich die gesuchte Zeile A erkennen kann.
Dann sollte es mit einem kleinen Programm machbar sein.
Da ich heute abend Zeit habe, Windows ksite läuft wegen problemen gerade nicht, könnte ich mich mal daran versuchen
Martin
könntest du mal ein längeres Testmuster per NoPaste oder als dl zur Verfügung stellen.
Würde gerne mal schauen was ich da tun könnte.
Ggf. würde ich mal wieder C/C++ ausgraben um damit mal ein kleines Testprogramm zu bauen was ggf. die Zeilennummer sucht und die Zeile ausgibt.
Ich bräuchte nur zu wissen wie Zeile B komplett lautet und wie ich die gesuchte Zeile A erkennen kann.
Dann sollte es mit einem kleinen Programm machbar sein.
Da ich heute abend Zeit habe, Windows ksite läuft wegen problemen gerade nicht, könnte ich mich mal daran versuchen
Martin
Es gibt keine if Schleife -> http://www.if-schleife.de/
Ansonsten GPL/GNU/Linux/Debian/Free Software 4 Ever
Ansonsten GPL/GNU/Linux/Debian/Free Software 4 Ever
Re: riesige Textdatei: einzelne (nicht unique) Zeile verände
Mein letzter Beitrag war eigentlich als Antwort auf deinen gedacht.cosmac hat geschrieben:Ach, übrigens darf jeder auf jeden Beitrag antworten...
Das wird mehr oder weniger eine einmalige Konvertierung sein. Vielleicht brauche ich sie noch ein bis zwei weitere Male, aber es ist keine regelmäßige Aufgabe.cosmac hat geschrieben:Wenn das zur Gewohnheit werden soll: ein C-Programm.
Ja, soweit die Zeilennummer zu ermitteln war bzw. bin ich schon. Im Grunde habe ich es so gemacht wie von cosmac vorgeschlagen. Nur was ich dann mit dieser Zeilennummer anfange ist mir noch nicht ganz klar. Ich hatte gehofft in man sed sowas wie einen Schalter für "beginne ab Zeile N" zu finden, aber leider ohne Erfolg. Und da dachte ich, statt mit grep und sed bzw. vi zu arbeiten geht das vielleicht mit ed.GoKi hat geschrieben:Wenn das das gewünschte Ergebnis liefert, kann man darüber Nachdenken die Zeile zu ändern.
Das geht leider nicht, da die Daten nicht meine sind.Milbret hat geschrieben:könntest du mal ein längeres Testmuster per NoPaste oder als dl zur Verfügung stellen.
Ich habe allerdings noch einen vielversprechenden Tipp für awk bekommen. Nur ist awk genau das Tool vor dem ich mich bisher gedrückt habe.
Re: riesige Textdatei: einzelne (nicht unique) Zeile verände
Naja, mit den zwei Suchen ist ed dann darauf vorbereitet die gesuchte Zeile zu bearbeiten. ed's aktuelle Zeile ist die gesuchte Zeile und Du kannst dann diese Zeile bearbeiten. Du kannst also z.B. irgendetwas ersetzen oder was auch immer. Das n Kommando war nur als Beispiel, um die aktuelle Zeile ausgeben zu lassen und somit das Ergebnis zu überprüfen. Du hast nicht genauer erläutert, was Du denn ändern möchtest.hikaru hat geschrieben:Ja, soweit die Zeilennummer zu ermitteln war bzw. bin ich schon. Im Grunde habe ich es so gemacht wie von cosmac vorgeschlagen. Nur was ich dann mit dieser Zeilennummer anfange ist mir noch nicht ganz klar. Ich hatte gehofft in man sed sowas wie einen Schalter für "beginne ab Zeile N" zu finden, aber leider ohne Erfolg. Und da dachte ich, statt mit grep und sed bzw. vi zu arbeiten geht das vielleicht mit ed.GoKi hat geschrieben:Wenn das das gewünschte Ergebnis liefert, kann man darüber Nachdenken die Zeile zu ändern.
Wie sich ed dann mit der 12GB Datei verhält musste man mal ausprobieren
MfG GoKi
:wq
:wq
Re: riesige Textdatei: einzelne (nicht unique) Zeile verände
Stimmt!GoKi hat geschrieben:Du hast nicht genauer erläutert, was Du denn ändern möchtest.
Nachdem ich mir nochmal deinen ersten Beitrag und man ed angesehen habe vermute ich, dass ich damit zum Ziel komme:
Code: Alles auswählen
$ ed -s test.txt << EOF
/B/
/A/
s/Suche/Ersatz/
n
w
EOF
1. test.txt einlesen (hier wird es spannend denn nach dem Einlesen gingen vi und nano in die Knie)
2. nach B suchen
3. ab Fundstelle von B nach A suchen
4. im gefundenen A A0 "Suche" durch "Ersatz" ersetzen
5. zur Kontrolle die veränderte Zeile nochmal ausgeben
6. Änderungen Schreiben
7. ed verlassen
Richtig?
-
- Beiträge: 134
- Registriert: 03.02.2011 11:11:21
- Lizenz eigener Beiträge: MIT Lizenz
- Wohnort: Frankfurt
Re: riesige Textdatei: einzelne (nicht unique) Zeile verände
Code: Alles auswählen
awk '/B/ {found=1;print;next}
/A/ {if (found) {sub("A","X");found=0;print;next}}
{print}
' test.txt
Re: riesige Textdatei: einzelne (nicht unique) Zeile verände
Die Methode für ed würde wahrscheinlich funktionieren, braucht aber vermutlich sehr viel Arbeitsspeicher, aber keinen Platz auf der HD.
Die awk-Methode oder andere serielle Methoden sind wahrscheinlich besser geeignet für große Dateien, aber bei Ausgabe in eine zweite Datei muss der Platz auf der HD vorhanden sein.
Ich würd's bei ner einmaligen Geschichte einfach mit awk machen, bei mehrmaliger Anwendung C/C++.
Die awk-Methode oder andere serielle Methoden sind wahrscheinlich besser geeignet für große Dateien, aber bei Ausgabe in eine zweite Datei muss der Platz auf der HD vorhanden sein.
Ich würd's bei ner einmaligen Geschichte einfach mit awk machen, bei mehrmaliger Anwendung C/C++.
MfG GoKi
:wq
:wq
Re: riesige Textdatei: einzelne (nicht unique) Zeile verände
fusecompress ?ich habe hier eine Textdatei von gut 12GB Größe.
Würde wohl auf einige dutzend MB zusammenschmelzen.
mfg rendegast
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")
-
- Beiträge: 134
- Registriert: 03.02.2011 11:11:21
- Lizenz eigener Beiträge: MIT Lizenz
- Wohnort: Frankfurt
Re: riesige Textdatei: einzelne (nicht unique) Zeile verände
Mit sed könnte man sowas machen:
Das A_Muster muss eindeutig für die A-Zeilen sein, d.h. es darf in den Zeilen von B bis zur Zeile vor dem nächsten A nicht vorkommen.
Der Mutige kann zusätzlich noch sed's Inplace-Option (-i, --in-place) anwenden
Code: Alles auswählen
sed '/B/,/A/ s/A_Muster/A_Ersetzung/' test.txt
Der Mutige kann zusätzlich noch sed's Inplace-Option (-i, --in-place) anwenden
Re: riesige Textdatei: einzelne (nicht unique) Zeile verände
Ok, die Sache ist erledigt. Danke für alle Tipps!
Im Einzelnen:
Mit ed hätte es prinzipiell funktioniert, aber ed arbeitet nicht auf dem Hauptspeicher sondern in einer temporären Datei im Home-Verzeichnis. 12GB habe ich da aber nicht frei und der Speicherort der temporären Datei lässt sich offenbar nicht ändern.
newdebs awk-Script hat problemlos funktioniert und nachdem ich mir dann auch nochmal man awk angeschaut habe glaube ich jetzt zumindest ein grundlegendes Verständnis davon zu haben. Ich habe das Ergebnis an einem kleinen Testdatenbestand (ca. 1GB) mit diff überprüft. Beim Test an der 12GB-Datei ist mir aufgefallen, dass diff (vermutlich) bei 16GB (beide Inputs zusammen) an seine Grenzen stößt. Jedenfalls brach es mit einer "out of memory"-Meldung ab.
Die sed-Variante hätte auch funktioniert. Zumindest tat sie das auf den Testdaten.
Im Einzelnen:
Mit ed hätte es prinzipiell funktioniert, aber ed arbeitet nicht auf dem Hauptspeicher sondern in einer temporären Datei im Home-Verzeichnis. 12GB habe ich da aber nicht frei und der Speicherort der temporären Datei lässt sich offenbar nicht ändern.
newdebs awk-Script hat problemlos funktioniert und nachdem ich mir dann auch nochmal man awk angeschaut habe glaube ich jetzt zumindest ein grundlegendes Verständnis davon zu haben. Ich habe das Ergebnis an einem kleinen Testdatenbestand (ca. 1GB) mit diff überprüft. Beim Test an der 12GB-Datei ist mir aufgefallen, dass diff (vermutlich) bei 16GB (beide Inputs zusammen) an seine Grenzen stößt. Jedenfalls brach es mit einer "out of memory"-Meldung ab.
Die sed-Variante hätte auch funktioniert. Zumindest tat sie das auf den Testdaten.
Re: [gelöst] riesige Textdatei: einzelne (nicht unique) Zeil
Sehr gut newdeb.
... ich war leider zur rechten Zeit nicht da.
... ich war leider zur rechten Zeit nicht da.
Use ed once in a while!