große Textdatei per Script bereinigen

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
teal
Beiträge: 288
Registriert: 05.10.2003 21:29:28

große Textdatei per Script bereinigen

Beitrag von teal » 10.12.2008 16:50:30

Hallo Forum,

ich habe mehrere große Textdateien (mehrere X-Tausend Zeilen pro Datei) welche ich von unsäglichen Leerzeilen bereinigen muss. Wie stelle ich das am geschicktesten an?

MfG,
teal

Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Re: große Textdatei per Script bereinigen

Beitrag von Duff » 10.12.2008 16:52:36

Kann dir zwar nicht sagen, ob es performant ist, aber mir fällt da nur perl oder sed ein.
Oh, yeah!

Benutzeravatar
teal
Beiträge: 288
Registriert: 05.10.2003 21:29:28

Re: große Textdatei per Script bereinigen

Beitrag von teal » 10.12.2008 17:17:58

Die Performace ist eigentlich egal. Das Problem ist, ich kenne mich weder in perl noch in sed aus. Hinzu kommt noch, dass ich "einzelne" Leerzeilen beibehalten möchte, nur wenn beispielsweise Zwei, drei oder Xbeliebige Leerzeilen hintereinander folgen möchte ich alle Leerzeilen bis auf die erste löschen.
Ich suche gerade was im Netz rum, ohne Perl Wissen stoße ich hier allerdings nicht wirklich tief vor...
format y: /FS:NTFS

Benutzeravatar
detix
Beiträge: 1743
Registriert: 07.02.2007 18:51:28
Wohnort: MK

Re: große Textdatei per Script bereinigen

Beitrag von detix » 10.12.2008 17:59:49

Eine Möglichkeit ist

Code: Alles auswählen

cat -s datei.txt
eine Andere mit sed und direkter Änderung der Datei

Code: Alles auswählen

sed -i '/./,/^$/!d' datei.txt
Bei mehreren Dateien schreib eine 'for... do' Schleife drumherum.
Gruß an alle Debianer, und immer daran denken:
Macht ohne Haftung funktioniert nicht!

Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Re: große Textdatei per Script bereinigen

Beitrag von Duff » 10.12.2008 19:47:40

Da nicht jede Leerzeile sed -e '/^$/d' datei gelöscht werden soll, sondern nur weiter Leerzeilen, finde ich die Lösung von detix sehr gut und geschickt. Wäre ich so ohne weiteres nicht drauf gekommen.

Es wird nun alles von /./ = irgendetwas bis /^$/ Leerzeile nicht gelöscht !d.
Oh, yeah!

Benutzeravatar
teal
Beiträge: 288
Registriert: 05.10.2003 21:29:28

Re: große Textdatei per Script bereinigen

Beitrag von teal » 10.12.2008 19:53:56

Das Ganze (beide varianten) haben leider nicht funktioniert.
Ich habe festgestellt, dass jede Zeile mindestens 4 Leerzeichen enthält. Sprich es sind keine Leerzeilen, da sie ja einen Inhalt haben. Kann man das irgendwie in sed anhängen?
format y: /FS:NTFS

Spasswolf
Beiträge: 3472
Registriert: 30.11.2005 10:32:22
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Wald

Re: große Textdatei per Script bereinigen

Beitrag von Spasswolf » 10.12.2008 20:02:11

Code: Alles auswählen

grep -v "^$" Datei
funktioniert hier.

Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Re: große Textdatei per Script bereinigen

Beitrag von Duff » 10.12.2008 20:05:48

Spasswolf hat geschrieben:

Code: Alles auswählen

grep -v "^$" Datei
funktioniert hier.
Dies entfernt alle Leerzeilen, aber sollten ja nur die darauffolgenden gelöscht werden. Wobei das auch nicht mehr stimmt, weil mit Leerzeilen nämlich Leerzeichen gemeint sind ;-)
Oh, yeah!

Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Re: große Textdatei per Script bereinigen

Beitrag von Duff » 10.12.2008 20:08:51

Habe es mal so probiert. So wird allerdings noch nichts in der original DAtei geändert. Dazu müsstest du dann den Schalter -i verwenden.
ABer zum Prüfen sollte es OK sein.

Code: Alles auswählen

daniel@daniel-laptop:/tmp$ sed -n 's/\s\{2,\}/ /g;p' test
Zeil 1 gefolgt von... nur ein oder mehre 

Leerzeile Leerzeile


noch weitere Leerzeilen
mit Zeilenumbruch und

Ende.
daniel@daniel-laptop:/tmp$ cat test
Zeil  1 gefolgt      von... nur  ein       	oder mehre   

Leerzeile  Leerzeile


noch weitere Leerzeilen
mit Zeilenumbruch und

Ende.
Oh, yeah!

resi
Beiträge: 14
Registriert: 14.07.2003 15:25:11

Re: große Textdatei per Script bereinigen

Beitrag von resi » 11.12.2008 16:34:14

Code: Alles auswählen

# Ich verwende da immer Python, paste das ganze in ein file.py, und rufe das ganze mit python file.py auf
# ohne argumente wird dieses file selbst als Testfile hergenommen, kannst aber auch ein oder mehrere
# Files als Argumente uebergeben, allerdings geht das Ergebnis aufs Terminal.
# Leerzeilen _und_ Leerzeichen muessen hier beachtet werden.


import sys


for arg in sys.argv:

    blank=False

    for line in open(arg):
        len = line.strip()
        if len:
            print line,
            blank = False
        else:




            if blank == False:
                print line,



                blank = True

Benutzeravatar
detix
Beiträge: 1743
Registriert: 07.02.2007 18:51:28
Wohnort: MK

Re: große Textdatei per Script bereinigen

Beitrag von detix » 11.12.2008 16:45:30

teal, wenn sonst keine Überraschungen mehr kommen :wink:
probiers auch mal damit

Code: Alles auswählen

sed -i 's/^ *$//;/./,/^$/!d' datei.txt
Gruß an alle Debianer, und immer daran denken:
Macht ohne Haftung funktioniert nicht!

resi
Beiträge: 14
Registriert: 14.07.2003 15:25:11

Re: große Textdatei per Script bereinigen

Beitrag von resi » 11.12.2008 17:10:49

prima, das ist eindeutig kürzer.
Es ist zwar nicht so gut lesbar und verarbeitet noch keine Tabs,
aber das lässt sich sicher auch noch verbessern.

Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Re: große Textdatei per Script bereinigen

Beitrag von Duff » 11.12.2008 17:11:09

Also das Beispiel von dir detix, funktioniert bei mir nicht.

Die Beispiel-Datei mit den Leerzeichen sieht so aus:

Code: Alles auswählen

daniel@daniel-laptop:/tmp$ cat test
zeil  1 gefolgt      von... nur  ein          oder mehre   

Leerzeile  Leerzeile


noch weitere Leerzeilen
mit 	Zeilenumbruch  und

Ende. ABC	 DEF  GH
Und die sed-Bearbeitung:

Code: Alles auswählen

daniel@daniel-laptop:/tmp$ sed -e 's/^ *$//;/./,/^$/!d' test
zeil  1 gefolgt      von... nur  ein          oder mehre   

Leerzeile  Leerzeile

noch weitere Leerzeilen
mit 	Zeilenumbruch  und

Ende. ABC	 DEF  GH
daniel@daniel-laptop:/tmp$ sed -n 's/\s\{2,\}/ /g;p' test
zeil 1 gefolgt von... nur ein oder mehre 

Leerzeile Leerzeile


noch weitere Leerzeilen
mit Zeilenumbruch und

Ende. ABC DEF GH
Oh, yeah!

Benutzeravatar
detix
Beiträge: 1743
Registriert: 07.02.2007 18:51:28
Wohnort: MK

Re: große Textdatei per Script bereinigen

Beitrag von detix » 11.12.2008 18:06:17

resi, für tabs könnte das reichen, nicht getestet

Code: Alles auswählen

sed -i 's/^[ t]*$//;/./,/^$/!d' datei.txt
Duff, ich hab die Nachfrage so verstanden,
das es bei ihm Zeilen gibt, die NUR Leerzeichen beinhalten und er nicht
2 oder mehr aufeinanderfolgende Leerzeichen durch eines ersetzen will,
mal abwarten...
Gruß an alle Debianer, und immer daran denken:
Macht ohne Haftung funktioniert nicht!

Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Re: große Textdatei per Script bereinigen

Beitrag von Duff » 11.12.2008 18:31:00

Ist auf jeden Fall lustig, da jeder eine andere Definition verstanden hat ;-)
Oh, yeah!

resi
Beiträge: 14
Registriert: 14.07.2003 15:25:11

Re: große Textdatei per Script bereinigen

Beitrag von resi » 12.12.2008 09:23:20

eher so

Code: Alles auswählen

sed -i 's/^[ \t]*$//;/./,/^$/!d' datei.txt
habs aber auch nicht getestet :-)

roli
Beiträge: 3174
Registriert: 10.09.2003 17:39:58

Re: große Textdatei per Script bereinigen

Beitrag von roli » 04.01.2009 17:48:00

Hi resi,
resi hat geschrieben:

Code: Alles auswählen

sed -i 's/^[ \t]*$//;/./,/^$/!d' datei.txt
kannst du dazu mal was sagen, irgendwie komme ich wenn ich mir ueberlege wie das Script arbeitet nie bis zum ende durch.
Roland


"Aber wenn du schon so unwissend bist, davon noch nicht gehört zu haben,
so will ich es doch als gut ansehen, daß du lieber einmal töricht fragst,
als weiterhin nichts von etwas zu wissen, das man doch wissen sollte."
aus "Die Edda des Snorri Sturluson", "Gylfis Täuschung"

Benutzeravatar
Meillo
Moderator
Beiträge: 9267
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: große Textdatei per Script bereinigen

Beitrag von Meillo » 04.01.2009 19:20:30

roli hat geschrieben:
resi hat geschrieben:

Code: Alles auswählen

sed -i 's/^[ \t]*$//;/./,/^$/!d' datei.txt
kannst du dazu mal was sagen, irgendwie komme ich wenn ich mir ueberlege wie das Script arbeitet nie bis zum ende durch.
Eigentlich ist es ja detixs Vorschlag (von weiter oben).

Ich habe im Dezember, als das Thema erstmals aktuell war, auch schon rumgerätselt wie detixs Vorschlag funktioniert, habe ihn dann aber einfach so hingenommen. (Hatte wenig Zeit.) Jetzt kommt es sehr gelegen wieder einzusteigen ... und durchzusteigen ;-)

Ich vereinfache den Aufruf mal zu:

Code: Alles auswählen

sed -i '/./,/^[ \t]*$/!d' datei.txt
(Das sollte äquivalent sein. Habe einige Fälle durchgetestet.)

Diese Anweisung bedeutet im Klartext:

Der `d' Befehl (= Zeile löschen) soll _nicht_ ausgeführt werde für die angegebenen Bereiche.

Die Bereiche zu verstehen ist etwas kompliziert, wie ich gerade gemerkt habe. Es ist so, dass das Kommando aktiviert wird, wenn die aktuelle Zeile auf die erste Adresse (/./) passt und deaktiviert wird, wenn sie auf die zweite (/^[ \t]*$/) passt.

Wenn man die Negierung noch auflöst, bedeutet es, dass das Kommando (`d' = aktuelle Zeile löschen) ausgeführt für alle Zeilen die nach einer leeren (oder nur-Whitespace) Zeile folgen bis zur jeweils nächsten nicht-leeren Zeile. Also alle auf die erste leere Zeile folgenden leeren Zeilen.

Da Negierungen schwer verständlich sind, habe ich das sed-Script mal umformuliert:

Code: Alles auswählen

sed -n  '/./,/^[ \t]*$/p' datei.txt
Das bedeutet: schreibe alle Zeilen die einer gefüllten Zeile nachfolgen heraus, bis zur ersten leeren Zeile (inklusive).

Es scheint dies wäre die beste sed-Lösung.

Am einfachsten verständlich ist aber wohl:

Code: Alles auswählen

sed 's/^[ \t]*$//' datei.txt | cat -s
D.h. mache alle nur-Whitespace-Zeilen komplett leer. Und. Mache aus mehrfachen Leerzeilen nur eine.


EDIT:
Geholfen hat mir übrigens, wie schon so viele Male, das Büchlein ``SED & AWK'' von Stephan Thesing von mitp ge-packt.
Use ed once in a while!

roli
Beiträge: 3174
Registriert: 10.09.2003 17:39:58

Re: große Textdatei per Script bereinigen

Beitrag von roli » 06.01.2009 21:30:50

Hi,
Meillo hat geschrieben:Eigentlich ist es ja detixs Vorschlag (von weiter oben).
Ups, trotzdem danke.
Meillo hat geschrieben:Die Bereiche zu verstehen ist etwas kompliziert, wie ich gerade gemerkt habe. Es ist so, dass das Kommando aktiviert wird, wenn die aktuelle Zeile auf die erste Adresse (/./) passt und deaktiviert wird, wenn sie auf die zweite (/^[ \t]*$/) passt.
Das Komma hat mich immer wieder raus gebracht ...
Roland


"Aber wenn du schon so unwissend bist, davon noch nicht gehört zu haben,
so will ich es doch als gut ansehen, daß du lieber einmal töricht fragst,
als weiterhin nichts von etwas zu wissen, das man doch wissen sollte."
aus "Die Edda des Snorri Sturluson", "Gylfis Täuschung"

Antworten