Anzeige:
Ergebnis 1 bis 4 von 4

Thema: Messdaten extrahieren/zeilenweise kopieren mit sed(?)

  1. #1
    jori
    Gast

    Messdaten extrahieren/zeilenweise kopieren mit sed(?)

    Hallo,

    Ich habe den Wunsch aus mehreren Messdaten (*.dat)

    -die ersten 8 Zeilen, (sed-Magie1)

    -Zeile 100 (sed-Magie2)

    -Zeile 250 (sed-Magie3)

    -und die Zeile in der MUSTER (; 2.00) zum ersten Mal vorkommt (sed-Magie4)

    in eine Datei zu schreiben die vor dem alten Dateinamen noch ein edit (o.ä.) stehen hat


    Ich bin noch "blutiger" Anfänger im Skripteschreiben, trotzdem der Versuch es darzustellen:


    #!/bin/bash

    DAT="*.dat" #charateristische Endung der Messdateien

    for f in $DAT
    do

    cat $f | sed -e "sed-Magie1" <$f >tmp.$$
    -e "sed-Magie2" <$f >>tmp$$ #um Ausgabe von Befehl2 an tmp.$$ anzuhängen(?)
    -e "sed-Magie3" <$f >>tmp$$
    -e "sed-Magie4" <$f >>tmp$$
    mv tmp.$$ edit$f
    done


    Mir fehlen aber noch die entscheidenden Formeln das ganze zu verwirklichen.
    ich danke euch im Vorraus

    Johannes

  2. #2
    Registrierter Benutzer
    Registriert seit
    07.05.2007
    Beiträge
    656
    Moin,

    zuerst ein paar Bemerkungen zu Deinem Script:

    Zitat Zitat von jori Beitrag anzeigen
    #!/bin/bash

    DAT="*.dat" #charateristische Endung der Messdateien

    for f in $DAT
    do

    cat $f | sed -e "sed-Magie1" <$f >tmp.$$
    -e "sed-Magie2" <$f >>tmp$$ #um Ausgabe von Befehl2 an tmp.$$ anzuhängen(?)
    -e "sed-Magie3" <$f >>tmp$$
    -e "sed-Magie4" <$f >>tmp$$
    mv tmp.$$ edit$f
    done
    - cat ist überflüssig, Du kannst sed den Dateinamen direkt als Argument übergeben.
    - <$f ist doppelt gemoppelt, damit fütterst Du sed aus der Pipe und aus STDIN
    - Die Ein- und Ausgabeumleitung zwischen den einzelnen -e-Optionen wird nicht funktionieren, das hängt man hinter die letzte Option bzw. das letzte Argument.
    - Mehrere sed-Kommandos kann man mit Semikolon trennen, das ist übersichtlicher als viele -e-Optionen

    So, und nun zum Thema: Ich habe mir erstmal Beispieldaten gebastelt:
    Code:
    jan@jack:~/tmp> for i in `seq 1 1000`; do echo -n "line $i" >>daten; test $i -eq 123 -o $i -eq 555 && echo -n " ;2.00 blablubb" >>daten; echo >>daten; done
    jan@jack:~/tmp> sed 's/^/data2 /' daten >data2
    So, und jetzt die Schleife + sed:
    Code:
    jan@jack:~/tmp> for dat in dat*; do
    > sed -rn '1,8p;100p;250p;/;2\.00/H;${g;s/\n(.+)\n.*/\1/;p}' $dat >>edit.txt
    > done
    jan@jack:~/tmp> cat edit.txt
    data2 line 1
    data2 line 2
    data2 line 3
    data2 line 4
    data2 line 5
    data2 line 6
    data2 line 7
    data2 line 8
    data2 line 100
    data2 line 250
    data2 line 123 ;2.00 blablubb
    line 1
    line 2
    line 3
    line 4
    line 5
    line 6
    line 7
    line 8
    line 100
    line 250
    line 123 ;2.00 blablubb
    Ist nur oberflächlich getestet.

    Jan

    EDIT: Mit ist noch eine Möglichkeit eingefallen, wie man die erste Zeile, die ";2.00" matcht, in der richtigen Reihenfolge ausgibt (das vorige Beispiel hat sie ja angehängt):
    Code:
    sed -rn '1,8p;100p;250p;/;2\.00/{x;/^$/{x;p};h}' daten
    Das sollte ich vielleicht doch mal kurz kommentieren ;-)

    Die ersten 3 Anweisungen ("1,8p;100p;250p;") sind wohl klar. Die nächste geschachtelte Anweisung ist die knifflige:

    "/;2\.00/{...}" - Wenn die Zeile matcht, dann führe den Codeblock in den äußeren {} aus

    "x;/^$/{x;p}" - tausche Inhalt von hold und pattern space aus (der Pattern space beinhaltet den Match, also hier die betreffende Zeile). Wenn jetzt der Pattern Space leer ist (beim ersten Treffer), dann tausche wieder Pattern und Hold Space (jetzt haben wir im Pattern Space wieder unsere Zeile) und gib sie aus.

    "h" - Kopiere den Inhalt des Pattern Space (unsere Zeile) in den Hold Space; damit steht nach dem ersten Treffer im Hold Space diese Zeile und ist bei den nächsten Anfrage nicht mehr leer - voila!

    Komisch - ich hatte doch noch was angehängt; wohl vergessen zu speichern - naja: Wenn eine Zeile, auf die das Pattern matcht, zufälligerweise eine der in den Zeilennummern aufgeführten ist, dann wird sie 2x ausgegeben. Das verhindert man, indem man die Reihenfolge der Anweisungen vertauscht (erst das PAttern, dann der Rest) und für das Pattern noch ein "d" (lösche den Pattern Space und mache mit der nächsten Zeile weiter) einfügt:
    Code:
    sed -rn '/;2\.00/{x;/^$/{x;p};h;d};1,8p;100p;250p' daten
    Es lässt mich nicht los ;-) die letzte Version behandelt die Regel "nur die erste auf ;2.00 matchende Zeile ausgeben" mit höherer Priorität als die Regel "Zeilen 1..8, 100, 250 ausgeben". Wenn also eine 2. Zeile innerhalb der gewünschten Zeilennummern auch das Pattern enthält, dann wird sie nicht ausgegeben.

    Wenn man es andersrum haben will, dann modifiziert man so:
    Code:
    sed -rn '/;2\.00/{x;/^$/{x;p;h;d};x;h};1,8p;100p;250p' daten
    Ob das überhaupt auftreten kann, weiss ich nicht - vielleicht sind die Zeilen, die per Zeilennummer ausgegeben werden, ja irgendwelche Header oder Überschriften - eben nur für alle Fälle.

    Nimmt das denn gar kein Ende? ;-) Es gibt ja noch eine Variante (da sieht man mal, was mangelnde Spezifikation ausrichtet): Gesetzt den Fall, dass die Zeilennummern höhere Priorität haben und eventuelle Matches gegen das Pattern bei ihnen überhaupt nicht berücksichtigt werden sollen:
    Code:
    sed -rn '1,8{p;d};100{p;d};250{p;d};/;2\.00/{x;/^$/{x;p};h}' daten
    So, jetzt ist aber genug!
    Geändert von jan61 (11-05-2009 um 21:15 Uhr)

  3. #3
    jori
    Gast
    @jan:

    Danke, Danke!

    Es hat geklappt und war lehrreich! Bitte entschuldige die mangelnde Spezifikation.

    Gruß

    Johannes

  4. #4
    Registrierter Benutzer
    Registriert seit
    07.05.2007
    Beiträge
    656
    Moin,

    Zitat Zitat von jori Beitrag anzeigen
    Bitte entschuldige die mangelnde Spezifikation.
    War nicht bös gemeint - manchmal denkt man als "Insider" schlicht und einfach nicht daran, dass Außenstehende die eine oder andere zusätzliche Info benötigen, um sich eine Vorstellung machen zu können - geht mir auch dann und wann so. Am besten ist immer ein kurzes Beispiel (es müssen ja nicht gleich 250 Zeilen sein ;-)

    Jan

    P.S.: Welche Variante hat denn gepasst?

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •