Seite 1 von 1
Zeilen Filtern
Verfasst: Samstag 25. Juni 2011, 12:49
von mzh
Liebes Forum
Ich habe ein File 'file.dat', welches so aussieht:
Nun will ich nur die 'data line's behalten. Von anderer Seite wurde mir nahegelegt das mit AWK zu erledigen. Auf der Shell direkt würde ich das etwa so erledigen
Code: Alles auswählen
awk '/data/,//' file.dat > data.dat
mv data.dat file.dat
Wenn ich das nun aus Python heraus machen möchte (also mit subprocess.Popen) fällt mir nichts besseres ein als der Umweg über ein temporäres File.
Code: Alles auswählen
awkCmd = '/data/,//'
target = open('file.dat', 'r')
awkp = subprocess.Popen(['awk', awkCmd],
stdin=target,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=False)
# Opening the 'data'-only file.
dataFile = open('data.tmp', 'w')
dataFile.write(awkp.stdout.read())
dataFile.close()
mvp = subprocess.Popen(['mv',
'data.tmp',
'file.dat'])
Wie kann man das eleganter erledigen?
Re: Zeilen Filtern
Verfasst: Samstag 25. Juni 2011, 12:54
von cofi
Auch wenn die Frage fehlt:
Code: Alles auswählen
In [12]: f = """info line Info i
info line Info j
data line data k
data line data l"""
In [16]: lines = f.split('\n')
In [17]: filter(lambda l: l.startswith("data"), lines)
Out[17]: [u'data line data k', u'data line data l']
Re: Zeilen Filtern
Verfasst: Samstag 25. Juni 2011, 12:55
von mzh
@cofi: Frage war in Vorbereitung.
Re: Zeilen Filtern
Verfasst: Samstag 25. Juni 2011, 15:15
von problembär
mzh hat geschrieben:Liebes Forum
Ich habe ein File 'file.dat', welches so aussieht:
Nun will ich nur die 'data line's behalten. Von anderer Seite wurde mir nahegelegt das mit AWK zu erledigen.
Eigentlich ist das die Hauptaufgabe des Shell-Befehls 'grep':
cofi's Vorschlag funktioniert bestimmt, aber ich bin zu faul, ihn zu verstehen. Deshalb würde ich es in Python einfach so machen:
Code: Alles auswählen
#!/usr/bin/env python
# coding: iso-8859-1
f = """info line Info i
info line Info j
data line data k
data line data l"""
lines = f.split('\n')
for i in lines:
if i.startswith("data"):
print i
Gruß
Re: Zeilen Filtern
Verfasst: Samstag 25. Juni 2011, 15:54
von mzh
@problembär
Danke für den Hinweis. Worauf ich mit dem Post hinaus wollte ist weniger das Filtern der Zeilen, eher darauf, ob es nicht anders geht als ein temporäres File zu öffnen. Kann man das nicht eleganter machen? Besonders den abschliessenden 'mv' call finde ich etwas grob.
Code: Alles auswählen
Python 2.4.3 (#2, Jan 21 2010, 19:56:43)
[GCC 4.0.3 (Ubuntu 4.0.3-1ubuntu5)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> print filter.__doc__
filter(function or None, sequence) -> list, tuple, or string
Return those items of sequence for which function(item) is true. If
function is None, return the items that are true. If sequence is a tuple
or string, return the same type, else return a list.
>>>
Re: Zeilen Filtern
Verfasst: Samstag 25. Juni 2011, 17:53
von LivingOn
in Anlehnung an den Vorschlag von Cofi als Einzeiler:
Code: Alles auswählen
python -c 'import sys;[sys.stdout.write(l) for l in sys.stdin if l.startswith("data")]' < test.dat
Re: Zeilen Filtern
Verfasst: Samstag 25. Juni 2011, 21:21
von EyDu
@mzh: Es hängt davon ab, wie viele Daten du verarbeitest. Du kannst natürlich die komplette Ausgabe in den Arbeitsspeicher lesen und dann in einem rutsch abspeichern. Ansosten ist eine temporäre Datei das einfachste. Für temporäre Dateien gibt es sogar ein extra Modul und Dateien solltest du mimtels with-Statement öffnen.
@LivingOn: Eine LC solltest du nur dann verwenden, wenn du die liste auch wirklich danach brauchst. Alles andere ist unerwartetes verhalten. Als Einzeiler mit einer einfache for-Schleife und einer if-Bedingung ist der Code auch nicht länger.
@problembär: Nun verstehe ich deine
Verständnisprobleme, du hast einfach keine Lust dir unbekannte Funktionen anzuschauen. Beides sogar Elemente aus der funktionalen Welt
Sebastian
Re: Zeilen Filtern
Verfasst: Samstag 25. Juni 2011, 23:05
von problembär
EyDu hat geschrieben:@problembär: Nun verstehe ich deine
Verständnisprobleme, du hast einfach keine Lust dir unbekannte Funktionen anzuschauen. Beides sogar Elemente aus der funktionalen Welt

Hehe, nein, das kommt von meiner Perl-Herkunft. Dort ist Faulheit eine ausdrückliche
Tugend des Programmierers. In diesem Sinne war das gemeint.
Gruß
Re: Zeilen Filtern
Verfasst: Sonntag 26. Juni 2011, 12:07
von mzh
LivingOn hat geschrieben:in Anlehnung an den Vorschlag von Cofi als Einzeiler:
Code: Alles auswählen
python -c 'import sys;[sys.stdout.write(l) for l in sys.stdin if l.startswith("data")]' < test.dat
Das "Problem" mit der temporären Datei wird dadurch ja nicht gelöst. Wofür ich eine elegante Lösung suche ist, wie kann man eine Datei lesen/filtern und den gefilterten Inhalt zurück in die gleiche Datei schreiben, ohne einen Umweg über eine temporäre Datei zu machen. Die Frage, wie man am besten den Filter in Python implementiert find ich gerade weniger interessant.
Re: Zeilen Filtern
Verfasst: Sonntag 26. Juni 2011, 12:53
von cofi
mzh hat geschrieben:Das "Problem" mit der temporären Datei wird dadurch ja nicht gelöst. Wofür ich eine elegante Lösung suche ist, wie kann man eine Datei lesen/filtern und den gefilterten Inhalt zurück in die gleiche Datei schreiben, ohne einen Umweg über eine temporäre Datei zu machen. Die Frage, wie man am besten den Filter in Python implementiert find ich gerade weniger interessant.
Nein, _genau das_ ist der interessante Teil. Wenn du die Daten in Python hast, kannst du sie problemlos wieder in diesselbe Datei schreiben. Wie EyDu aber schon angedeutet hat, macht die temporäre Datei durchaus Sinn, wenn man beispielsweise mit großen Dateien arbeitet.
Re: Zeilen Filtern
Verfasst: Sonntag 26. Juni 2011, 12:54
von BlackJack
@mzh: Das geht ohne temporäre Datei nicht wirklich elegant. Wenn man weiss, dass die gefilterte Datei zu jedem Zeitpunkt/Programmschritt kleiner als die ungefilterte ist, kann man das zwar machen, aber es ist IMHO nicht elegant. Bei einem Programmabbruch, aus welchem Grund auch immer, hat man zum Beispiel eine Datei, deren Inhalt irgendwo zwischen gefiltert und ungefiltert steht. Bei einer temporären Datei hat man immer nur genau einen der beiden Zustände in der Ursprungsdatei.