[gelöst] egrep Ergenbis in einer Zeile

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
gugus
Beiträge: 381
Registriert: 04.09.2002 17:41:17
Wohnort: da wo ich zu Hause bin

[gelöst] egrep Ergenbis in einer Zeile

Beitrag von gugus » 27.04.2022 13:25:25

Servus Leutz
Ich habe Email Dateien in eml Format und möchte das Ergenbis aus einem egrep in einer Zeile speichern.

Ich möchte das Datum sowie den Messwert in einer Zeile haben.

Datum; Messwert
25.04.22 ; 97.25

Der egrep Befehl und Ergebnis

Code: Alles auswählen

egrep '(Datum|Messung)' datei.eml

datei.eml:Aktuelles Datum / Zeit : Es ist der 25.04.22 - 06:00:00 Uhr
datei.eml:f_distanz direkt nach Messung ..................: 97.25


Verschiedene Versuche mit sed schlagen fehl da der 2. String den ersten überschreibt.

Code: Alles auswählen

egrep '(Datum|Messung)' datei.eml |  sed 'N;s/\n/;/g'
Ausgabe:
f_distanz direkt nach Messung ..................: 97.25 Uhr

Oder kann ich gleich mit awk die beiden parameter filtern und ausgeben?
Da ich kein grosser Scripter bin frage ich mal nach was ich falsch mache oder meine Überlegung falsch ist.

gruss
Zuletzt geändert von gugus am 27.04.2022 17:05:51, insgesamt 1-mal geändert.

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

Re: egrep Ergenbis in einer Zeile

Beitrag von Meillo » 27.04.2022 13:52:17

Es scheint mir, dass in der Mail \r\n Zeilenumbrueche drin sind. Du entfernst das \n aber das verbleibende \r sorgt dafuer, dass die zweite Zeile ueber die erste geschrieben wird.

Du kannst das testen indem du die Ausgabe durch `od -c' pipest.

Loesen kannst du es indem du \r auch entfernst.
Use ed once in a while!

gugus
Beiträge: 381
Registriert: 04.09.2002 17:41:17
Wohnort: da wo ich zu Hause bin

Re: egrep Ergenbis in einer Zeile

Beitrag von gugus » 27.04.2022 15:11:16

Hm, ich habe einiges rumprobiert, bis anhin ohne Ergebnis.

unter anderem habe ich

Code: Alles auswählen

sed ":a;/\r$/{$!N;s/\r\n//;t a};s/\r//g"
sed -z 's/\r\n//'
ausprobiert, aber dann fehlen sämtliche cr/lf und das Ergebnis kommt "am Stück"
Eventuell muss ich mich vom Einzeiler verabschieden und es in einer Schleife mit jedem einzelnen Email lösen.

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

Re: egrep Ergenbis in einer Zeile

Beitrag von Meillo » 27.04.2022 15:14:57

Poste doch mal die Ausgabe wenn du an deinen urspruenglichen Befehl noch `| od -c' anhaengst. Das wird viele Fragen klaeren. Dann koennen wir dir auch konkreter helfen und muessen nicht so viel raten.
Use ed once in a while!

gugus
Beiträge: 381
Registriert: 04.09.2002 17:41:17
Wohnort: da wo ich zu Hause bin

Re: egrep Ergenbis in einer Zeile

Beitrag von gugus » 27.04.2022 16:01:12

Also, ich musste die Ausgabe etwas anonymisieren und kürzen da noch ein paar Daten drin sind die nicht veröffentlicht werden sollen.
Von daher möchte ich auch nur das Datum der Messung und den entsprechenden Wert dahinter auflisten da es nur um den Messwert geht.
Die erstellte Datei wird automatisiert verschickt und in eine Tabelle eingelesen.

Der ursprüngliche Befehl erweitert mit od -c zeigt lf/cr nach jedem einzelnen egrep.
Daher ist Deine Vermutung mit dem /r richtig, aber das war mir schon klar.

Code: Alles auswählen


egrep '(Datum|Messung)' datei*.eml | od -c

...
...
0030000       -       2   0   2   2   -   0   4   -   2   5       0   6
0030020   0   0   .   e   m   l   :   A   k   t   u   e   l   l   e   s
0030040       D   a   t   u   m       /       Z   e   i   t       :    
0030060   E   s       i   s   t       d   e   r       2   5   .   0   4
0030100   .   2   2       -       0   6   :   0   0   :   0   0       U
0030120   h   r  \r  \n   x  x   x   x x   x   x   x   x   x   x    
...
...
0030320       M   e   s   s   u   n   g       .   .   .   .   .   .   .
0030340   .   .   .   .   .   .   .   .   .   .   .   :       9   7   .
0030360   2   5  \r  \n
0030364

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

Re: egrep Ergenbis in einer Zeile

Beitrag von Meillo » 27.04.2022 16:06:20

Na also, meine Vermutung hat sich bestaetigt.

Nun vermute ich erneut: Folgender Befehl tut was du willst:

Code: Alles auswählen

egrep '(Datum|Messung)' datei.eml | tr -d \\r | sed 'N;s/\n/;/g'
(Koennte man auch noch schoener schreiben, aber so ist es ganz simpel was passiert.)
Use ed once in a while!

gugus
Beiträge: 381
Registriert: 04.09.2002 17:41:17
Wohnort: da wo ich zu Hause bin

Re: egrep Ergenbis in einer Zeile

Beitrag von gugus » 27.04.2022 16:17:52

Yes Sir :THX:

Wenn ich jetzt noch die beiden Werte mittel awk -F " " {print $1" ; "print $2}' rausbekomme bin ich happy.
Natürlich ersetzt 1 und 2 die jeweilige Position im String.

Kann man wahrscheinlich auch etwas schöner machen.

Danke nochmal.
Gruss

uname
Beiträge: 12075
Registriert: 03.06.2008 09:33:02

Re: egrep Ergenbis in einer Zeile

Beitrag von uname » 27.04.2022 16:29:49

Ich denke man könnte auch nur awk verwenden. Hierfür müsste man nach Begriffen aus der jeweils ersten bzw. zweiten Zeile suchen und bei der ersten Zeile den Wert zwischenspeichern und bei der zweiten Zeile erst ausgeben. Wahrscheinlich wäre aber ein einzelner awk-Befehl dadurch länger. Vielleicht hat jemand Lust das kurz zu programmieren.

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

Re: egrep Ergenbis in einer Zeile

Beitrag von Meillo » 27.04.2022 16:30:49

Ach so. Ja, das kannst du auch einfacher haben:

Code: Alles auswählen

egrep '(Datum|Messung)' datei.eml | awk '/Aktuelles Datum/{printf "%s ; ", $(NF-3)} /f_distanz/{print $NF}'
Du kannst dir dabei das egrep auch ganz sparen:

Code: Alles auswählen

<datei.eml awk '/Aktuelles Datum/{printf "%s ; ", $(NF-3)} /f_distanz/{print $NF}'
Use ed once in a while!

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

Re: egrep Ergenbis in einer Zeile

Beitrag von Meillo » 27.04.2022 16:31:08

uname hat geschrieben: ↑ zum Beitrag ↑
27.04.2022 16:29:49
Vielleicht hat jemand Lust das kurz zu programmieren.
Schon erledigt. :-D
Use ed once in a while!

gugus
Beiträge: 381
Registriert: 04.09.2002 17:41:17
Wohnort: da wo ich zu Hause bin

Re: egrep Ergenbis in einer Zeile

Beitrag von gugus » 27.04.2022 17:05:28

Hoppala :mrgreen:

Ja, ich wollte an sich von Beginn an mit awk arbeiten, bin aber mit den vielen Optionen nicht schlau geworden.

Werde aber bei egrep bleiben da ich dann besser mit den input Dateien "spielen" kann.
Ich verwende die getrimmte Version und bekomme genau das was ich mir schon im 1. Post vorgestellt habe.:

Code: Alles auswählen

egrep '(Datum|Messung)' Datei*.eml | awk '/Aktuelles Datum/{printf "%s;", $(NF-3)} /f_distanz/{print $NF}'

31.03.22 ; 97.59
01.04.22 ; 102.41
02.04.22 ; 97.59
03.04.22 ; 103.09
04.04.22 ; 108.25
05.04.22 ; 97.25
06.04.22 ; 97.59
07.04.22 ; 92.78
08.04.22 ; 97.59
09.04.22 ; 97.94
10.04.22 ; 103.44
11.04.22 ; 100.69
12.04.22 ; 103.09
14.04.22 ; 92.44
15.04.22 ; 91.75
16.04.22 ; 93.13
17.04.22 ; 100.34
18.04.22 ; 100.69
19.04.22 ; 103.44
20.04.22 ; 98.28
13.04.22 ; 92.44
21.04.22 ; 103.09
22.04.22 ; 102.41
23.04.22 ; 102.41
24.04.22 ; 93.13
25.04.22 ; 97.25
Nochmals :THX:

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

Re: egrep Ergenbis in einer Zeile

Beitrag von Meillo » 27.04.2022 17:20:02

gugus hat geschrieben: ↑ zum Beitrag ↑
27.04.2022 17:05:28
Ja, ich wollte an sich von Beginn an mit awk arbeiten, bin aber mit den vielen Optionen nicht schlau geworden.

Werde aber bei egrep bleiben da ich dann besser mit den input Dateien "spielen" kann.
Wahrscheinlich ist dir das noch nicht bewusst, aber awk kann das gleiche was egrep auch kann ... und das ist fuer dich auch nicht schwieriger. Hier mal ein paar Entsprechungen:

Code: Alles auswählen

egrep '(Datum|Messung)'
awk '/(Datum|Messung)/'
Wenn man in awk keine Bloecke mit geschweiften Klammern verwendet, dann gibt es einfach die jeweilige Zeile aus und verhaelt sich damit wie egrep.


Hier nochmal dein Befehl:

Code: Alles auswählen

egrep '(Datum|Messung)' Datei*.eml | awk '/Aktuelles Datum/{printf "%s;", $(NF-3)} /f_distanz/{print $NF}'
Das

Code: Alles auswählen

/Aktuelles Datum/
im awk-Code macht genau das gleiche wie das

Code: Alles auswählen

Datum
bei egrep. (Ich habe bloss das Wort ``Aktuelles'' hinzugefuegt, damit es genauer ist.)

Gleichermassen verhaelt es sich bei ``Messung'' und ``f_distanz'' ... ich habe mir hier die Freiheit genommen, den Wertenamen zu nehmen, weil ich dachte, dass das genauer treffend sein wird als das Wort ``Messung''.


In awk kann man dann aber an verschiedene REs unterschiedliche Operationen koppeln, in der Weise:

Code: Alles auswählen

awk '
/Datum/ { ... }
/Messung/ { ... }
'
Wenn du statt den Punkten den Befehl `print' hinschreibst, dann wird die Zeile einfach ausgegeben. Du kannst an der Stelle aber auch andere Dinge tun, wie nur Teile der Zeile auszugeben (z.B. `print $3') oder die Anzahl der Woerter/Felder der Zeile ausgeben (`print NF') oder den Inhalt der Zeile veraendern (mit `sub()' bzw. `gsub()' identisch wie bei sed mit s///) oder Variablen setzen, Schleifen schreiben, usw.

Ich habe bei dem Befehl das viertletzte Feld (`$(NF-3)') bzw. das letzte Feld (`$NF') ausgegeben ... im ersten Fall mit `printf' ohne Newline und im zweiten Fall mit `print' mit.


Mit diesen Erklaerungen kommt der der awk-Befehl vielleicht gar nicht mehr so fremd vor und du erkennst die Naehe zu egrep, so dass du zukuenftig fliessend zwischen beiden hin und her wechseln kannst. :-)
Use ed once in a while!

gugus
Beiträge: 381
Registriert: 04.09.2002 17:41:17
Wohnort: da wo ich zu Hause bin

Re: [gelöst] egrep Ergenbis in einer Zeile

Beitrag von gugus » 27.04.2022 21:04:34

Super, Danke für die Erklärung.
Einen Teil habe ich schon begriffen, mir war die Verwendung von Feldern ( $(NF-3) ) nicht ganz klar. Aber dies ist ja Teil von printf.
Vor allem dass bei awk es auch kein Problem darstellt wenn im String Steuerzeichen wie eben lf/cr vorkommen.

Da ich nur "alle Jahre" etwas komplizierteres zu verarbeiten habe ist es nicht so einfach alles immer parat zu haben. :mrgreen:
Aber der awk wird mir in Erinnerung bleiben.

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

Re: [gelöst] egrep Ergenbis in einer Zeile

Beitrag von Meillo » 27.04.2022 21:14:15

gugus hat geschrieben: ↑ zum Beitrag ↑
27.04.2022 21:04:34
[...] mir war die Verwendung von Feldern ( $(NF-3) ) nicht ganz klar. Aber dies ist ja Teil von printf.
Zu printf gehoert es nicht direkt. Es ist in dem Beispiel nur ein Wert, der dann von printf ausgegeben wird.

Bei awk ist das so:

Mit einem Dollarzeichen und einer Zahl dahinter kann man den Inhalt des xten Feldes ausgeben. $1 gibt das erste Feld aus $25 das fuenfundzwanzigste.

Dabei kann man auch Variablen verwenden. Um das vierte Feld auszugeben, beispielsweise so:

Code: Alles auswählen

n = 4
print $n
`NF' ist eine automatisch gesetzte Variable, die die Anzahl der Felder in der Zeile enthaelt. (Mnemonic: Number of Fields.)

`$NF' steht damit fuer den Wert des letzten Feldes.

Und damit kann man dann auch rechnen. `NF-1' ist die Nummer des vorletzten Feldes. Wenn man ein Dollarzeichen davor macht, ist es der Inhalt des Feldes. Man muss nur mit der Praezedenz aufpassen, darum die Klammern. Wir wollen schliesslich die Feldanzahl minus eins und davon den Inhalt und nicht den Inhalt des letzten Feldes und davon dann eins abziehen. ;-)
Use ed once in a while!

gugus
Beiträge: 381
Registriert: 04.09.2002 17:41:17
Wohnort: da wo ich zu Hause bin

Re: [gelöst] egrep Ergenbis in einer Zeile

Beitrag von gugus » 27.04.2022 21:25:07

so einfach kann es sein ..... :lol:

Antworten