PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : daten extrahieren



axelf
13-02-2008, 13:35
Hallo zusammen,

Ich habe eine Datei mit Messdaten.
(Zeilennummern sind keine in der Datei)
______________________________________________
1
2
3
4>#70160004B20BB21AB1D0B058AD3CAFE8B231B2C8B137B04DB 15
5 waiting for module ready
6.
7 done; module ready
9
10
11
12 terminating:
13>4 *loc
14>3 *loc
15 -0 errors detected-
16 -fertig-
__________________________________________________

aus dieser Datei interessiert mich nur Zeile 4

>#70160004B20BB21AB1D0B058AD3CAFE8B231B2C8B137B04DB 15


und zwar ab dem 11.Zeichen sprich nach ">#70160004..."
die folgenden Zahlen sind jeweils Binäre Hexwerte der Messung,wobei 4 Zeichen eine Hexzahl bilden : Also ....
B20B = HexZahl1
B21A = HexZahl2
B1D0 = HexZahl3 etc...

Was soll das Bashskript für mich erledigen ?
1. Die gewünschte Zeile 4 ab dem 11. Zeichen einlesen
2. jeweils die Hexzahlen aus diesem String extrahieren
3. die Hexzahlen in dezimalzahlen umwandeln
4. die Dezimalzahlen als csv in eine neue Datei schreiben

Meine ersten Gehversuche sehen wie folgt aus :
_______________________________________
#!/bin/bash

FILE="test.txt"

line= sed 4!d $FILE;

for (( i = 0 ; i <= 5; i++ ))
do
istart=$[31+$i*4];
istop=$[34+$i*4];

zahl= cut -b $istart-$istop $line | bc;

printf "%d\n",$zahl > ergebnis.txt

#echo "Schleife : $i times"
#echo "istart = $istart ; istop = $istop"
done
exit 0
__________________________________________

Leider geht es so nicht, und ich bin leider noch zu unerfahren um zu wissen woran es krankt...

Deswegen hoffe ich auf euere Unterstützung bzw. um Rat und Tat...

Gruß
Axel

jan61
13-02-2008, 23:08
Moin,

zuerst mein Standard-Ratschlag: Wenn Du wissen willst, was Dein Script macht, setze an den Anfang ein "set -x" - sozusagen der Debug-Modus der Shell. Dann schau Dir an, was da ausgegeben wird.

Und im Interesse besserer Lesbarkeit: Benutze für Code bitte auch das Code-Tag ("#" im erweiterten Modus des Forum-Editors).

Zu Deinen Wünschen:

Wenn Du die Ausgabe eines Kommandos in einer Variablen haben willst, dann musst Du die Form variable=`kommando` nutzen - die Backticks sind entscheidend. Und in Deinem Fall (sed) ist noch was zu beachten: Alles, was Sonderzeichen der Shell sein kann, muss gequotet werden:
jan@jack:~/tmp/messdaten> sed '4!d' test.txt
>#70160004B20BB21AB1D0B058AD3CAFE8B231B2C8B137B04 DB15
jan@jack:~/tmp/messdaten> sed 4!d test.txt
sed 4du -s * test.txt
sed: -e Ausdruck #1, Zeichen 3: Zusätzliche Zeichen nach dem Befehl
Hier schlägt der "!" zu und sucht mir den letzten mit "d" beginnenden Befehl aus meiner Bash-History. Ach ja - die Zeilen der test.txt können alles Mögliche beinhalten - also solltest Du auch das Ergebnis des sed quoten (was passiert z. B., wenn Zeile 4 nicht das erwartete enthält?). Und das Abschneiden der 10 Zeichen zum Anfang erledigen wir hier gleich mit:
jan@jack:~/tmp/messdaten> sed '4!d;s/^.\{10,10\}//' test.txt
B20BB21AB1D0B058AD3CAFE8B231B2C8B137B04 DB15
Da fällt mir auf: Da schwirrt noch ein Leerzeichen rum vor der letzten Hex-Zahl - Absicht? Wenn ja, dann kommt das auch noch mit weg:
jan@jack:~/tmp/messdaten> sed '4!d;s/^.\{10,10\}//;s/\s//g' test.txt
B20BB21AB1D0B058AD3CAFE8B231B2C8B137B04DB15
Wenn das Teil der Zahl sein soll (bei 1..3-stelligen Zahlen), dann ersetzen wir es durch eine 0:
jan@jack:~/tmp/messdaten> sed '4!d;s/^.\{10,10\}//;s/\s/0/g' test.txt
B20BB21AB1D0B058AD3CAFE8B231B2C8B137B04D0B15


So, jetzt das alles noch in eine Variable gepackt:

jan@jack:~/tmp/messdaten> zeile="`sed '4!d;s/^.\{10,10\}//;s/\s//g' test.txt`"
jan@jack:~/tmp/messdaten> echo "$zeile"
B20BB21AB1D0B058AD3CAFE8B231B2C8B137B04DB15
Zur Schleife: Du benutzt eine bunte Mischung aus C-Style und Shell. Die bash kann eine Menge ab, aber besser ist es IMHO, bei einer Syntax-Form zu bleiben. So z. B.:
jan@jack:~/tmp/messdaten> for pos in `seq 1 4 \`echo $zeile | wc -c\``; do
>echo $zeile | cut -c${pos}-`expr $pos + 3` | bc
>done
9209
9219
9190
9058
9939
9998
9231
9298
9137
9049
915
Mit einer zusätzlichen Prüfung, ob Deine ausgeschnittene Zeile auch das enthält, was Du erwartest, sieht das Ganze dann etwa so aus:

jan@jack:~/tmp/messdaten> cat get_messdaten.sh
#! /bin/bash

# 4. Zeile aus test.txt holen, Zeichen 1 - 10 loeschen, Leerzeichen loeschen
zeile="`sed '4!d;s/^.\{10,10\}//;s/\s//g' test.txt`"

# wenn Zeile nicht ausschliesslich Ziffern und A..F enthaelt: Fehler
test -n "`echo $zeile | sed 's/[0-9A-F]//g'`" && exit 1

# Verarbeitungsschleife
for pos in `seq 1 4 \`echo $zeile | wc -c\``; do
echo $zeile | cut -c${pos}-`expr $pos + 3` | bc
done >ergebnis.txt

exit 0
jan@jack:~/tmp/messdaten> ./get_messdaten.sh
jan@jack:~/tmp/messdaten> cat ergebnis.txt
9209
9219
9190
9058
9939
9998
9231
9298
9137
9049
915
Noch eine Bemerkung zur Ausgabe in die Datei ergebnis.txt: Wenn Du innerhalb der Schleife ausgeben willst, dann musst Du ">>" benutzen (anhängen), sonst überschreibst Du Dir in jedem Schleifendurchlauf die vorigen Ausgaben.

Jan

axelf
14-02-2008, 07:38
Super !!

Danke für deine schnelle Unterstützung und den ergänzenden Erklärungen !!!

Gruß
Axel