Zeilen Filtern

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
mzh
User
Beiträge: 295
Registriert: Dienstag 3. März 2009, 15:27
Wohnort: ZH

Liebes Forum
Ich habe ein File 'file.dat', welches so aussieht:

Code: Alles auswählen

info line i
info line j
data line k
data line l
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?
Zuletzt geändert von mzh am Samstag 25. Juni 2011, 12:54, insgesamt 1-mal geändert.
[url=http://www.proandkon.com]proandkon.com[/url]
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

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']
mzh
User
Beiträge: 295
Registriert: Dienstag 3. März 2009, 15:27
Wohnort: ZH

@cofi: Frage war in Vorbereitung.
[url=http://www.proandkon.com]proandkon.com[/url]
problembär

mzh hat geschrieben:Liebes Forum
Ich habe ein File 'file.dat', welches so aussieht:

Code: Alles auswählen

info line i
info line j
data line k
data line l
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':

Code: Alles auswählen

grep "data" file.dat
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ß
mzh
User
Beiträge: 295
Registriert: Dienstag 3. März 2009, 15:27
Wohnort: ZH

@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.
>>> 
[url=http://www.proandkon.com]proandkon.com[/url]
LivingOn
User
Beiträge: 33
Registriert: Montag 11. August 2008, 07:53

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
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

@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 :roll:

Sebastian
Das Leben ist wie ein Tennisball.
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 :roll:
Hehe, nein, das kommt von meiner Perl-Herkunft. Dort ist Faulheit eine ausdrückliche Tugend des Programmierers. In diesem Sinne war das gemeint. ;)

Gruß
mzh
User
Beiträge: 295
Registriert: Dienstag 3. März 2009, 15:27
Wohnort: ZH

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.
[url=http://www.proandkon.com]proandkon.com[/url]
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

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.
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.
Antworten