Grep and awk

Hallo Experten,

ich habe eine Menge Dateien, die zeilen- und spaltenweise Informationen enthalten. Dabei möchte ich jeweils zwei Spalten extrahieren und ein wenig das Zahlenformat von US-Notation mit Punkt in deutsche Kommaschreibweise modifizieren. Das klappt bis auf den Eintrag in der ersten Zeile mit folgendem Kommando:

grep „Sensor 4 C:“ flug2804_01.log | awk ‚{print $3 " " $7}‘ | awk ‚FS="."{print $1 „,“ $2}‘ > sensor04.txt

Der Output (cat sensor04.txt) sieht dann wie folgt aus:

15:27:11,26.25
15:28:10 26,31
15:29:10 26,25
15:30:10 26,31
15:31:10 26,25
15:32:10 26,25
15:33:10 26,31
15:34:10 26,31

Warum ist die erste Zeile anders?

Viele Grüße,
Ingo

Hallo Experten,

Hi,

wen meinst Du?

[Beschreibung]

Es waere wirklich total Klasse, wenigstens ein kurzes Beispiel der Eingangsdaten zu sehen. Irgendwie erahne ich, dass awk nicht das ist, was Du suchst.

Kommando:

awk ‚FS="."{print $1 „,“ $2}‘

Ich wuerde sagen, das ist nicht mal korrekte awk-Syntax. Ein awk-Kommando sieht ungefaehr so aus:

_[WHEN]_ _BLOCK_

dabei ist

_WHEN_ := ( BEGIN | END | _REGEXP_ )
_REGEXP_ := / _regulaerer Ausdruck_ /
_BLOCK_ := { _STATEMENTLIST_ }
_STATEMENTLIST_ := _STATEMENT_ [; _STATEMENTLIST_]

‚FS="."‘ passt eindeutig nicht auf WHEN, ich nehmen an, dass awk aus Deinem Kommando groszzuegigerweise sowas wie

$ awk '{FS="."; print $1 "," $2}'

oder

$ awk '{FS="."}{print $1 "," $2}'

macht. Und jetzt wird hoffentlich klarer, warum Du scheiterst: das erste statement wird erst im BLOCK ausgefuehrt, nachdem der erste record schon lange eingelesen und in Felder unterteilt wurde; fuer die weiteren ist er dann gesetzt. Du muszt den field separator vor dem ersten Einlesen aendern, zum Beginn, daher:

frank@zion [~] $ echo '15:27:11,26.25
\>15:27:11,26.25' |awk 'BEGIN{FS="."}{print $1, $2}'
15:27:11,26 25
15:27:11,26 25
frank@zion [~] $

Unabhaengig davon bin ich der Ueberzeugung, dass sed fuer Dich besser geeignet ist.

HTH,
Gruss vom Frank.

Moin,

wen meinst Du?

vielleicht Dich?

[Beschreibung]

Es waere wirklich total Klasse, wenigstens ein kurzes Beispiel

Ups, hätte ich gleich posten sollen. Hier ist es:

Apr 28 17:32:08 Sensor 0 C: 26.44 F: 79.59
Apr 28 17:32:09 Sensor 1 C: 26.50 F: 79.70
Apr 28 17:32:10 Sensor 2 C: 26.81 F: 80.26
Apr 28 17:32:11 Sensor 3 C: 26.31 F: 79.36
Apr 28 17:32:12 Sensor 4 C: 26.44 F: 79.59
Apr 28 17:32:13 Sensor 5 C: 26.44 F: 79.59
Apr 28 17:32:14 Sensor 6 C: 26.50 F: 79.70
Apr 28 17:32:15 Sensor 7 C: 26.44 F: 79.59
Apr 28 17:32:16 Sensor 8 C: 26.31 F: 79.36
Apr 28 17:32:17 Sensor 9 C: 26.44 F: 79.59
Apr 28 17:32:19 Sensor 10 C: 26.38 F: 79.47
Apr 28 17:32:20 Sensor 11 C: 26.38 F: 79.47
Apr 28 17:32:21 Sensor 12 C: 26.44 F: 79.59
Apr 28 17:32:22 Sensor 13 C: 26.94 F: 80.49
Apr 28 17:32:23 Sensor 14 C: 26.38 F: 79.47

und dann wieder die selbe Reihenfolge der Datensätze eine Minute später.

der Eingangsdaten zu sehen. Irgendwie erahne ich, dass awk
nicht das ist, was Du suchst.

Im Prinzip ist mir der Lösungsweg egal, sofern er funktioniert… und ich würde ihn gerne verstehen :wink:.

Kommando:

awk ‚FS="."{print $1 „,“ $2}‘

Ich wuerde sagen, das ist nicht mal korrekte awk-Syntax.

Nun, es meckerte zumindest nicht…

gesetzt. Du muszt den field separator vor dem ersten Einlesen
aendern, zum Beginn, daher:

aha…

*nachvollzieh*

ja, danke, es funktioniert mit der vorgeschlagenen Änderung:

awk '{print $3 " " $7}' sensor11.log | awk 'BEGIN{FS="."}{print $1 "," $2}' \> sensor11.txt

Besten Dank,
Ingo

*der sich sed trotzdem 'mal merken will*

Hi Ingo,

grep „Sensor 4 C:“ flug2804_01.log | awk ‚{print $3 " " $7}‘ |
awk ‚FS="."{print $1 „,“ $2}‘ > sensor04.txt

Awk nach awk pipen ist immer unschön un macht die ganze Angelegenheit sogar recht langsam. Das FS="." ist beim zweiten awk-Aufruf falsch, dadruch wird auch die erste Zeile falsch ausgegeben…warum auch immer. Den Fieldseparator hängst du entweder als Parameter mit an den awk-Aufruf (awk -F. ‚{…}‘) oder definierst ihn im awk-Programm (awk ‚BEGIN{FS=.}{…}END{…}‘)
Mit folgendem Einzeiler ohne Pipes gehts auch und sieht schöner aus

awk '{if($0~"Sensor 4 C"){gsub("\.",",",$7); print $3 " " $7}}' flug2804\_01.log

Das if ersetzt das grep und das gsub() ändert im 7ten Feld den „.“ zu nem „,“. Natürlich nur, wenn die if-Bedingung erfüllt ist.

Gruß
Martin