ubuntuusers.de

Mit bash Skript bestimmte Werte aus Tabelle lesen

Status: Ungelöst | Ubuntu-Version: Kubuntu 12.04 (Precise Pangolin)
Antworten |

naka95

Anmeldungsdatum:
9. Dezember 2015

Beiträge: 3

Hallo!

Ich beschäftige mich erst seit Kurzem mit bash und bin deshalb noch nicht so fit darin. Und nun habe ich schon ein kleines Problem und keine Lösung dazu gefunden:

Gegeben sind 3 Tabellen (Messung0, Messung1 und Messung2, siehe Anhang!) mit x- und y-Werten. Nun muss ich die Steigung zwischen zwei Punkten berechnen. Dabei würde ich die beiden x-Werte festlegen (hier 25 und 40) und die y-Werte sind je nach verwendeter Tabelle unterschiedlich.

Die Steigung berechne ich mit der Formel m=(y(40)-y(25))/40-25.

Ich weiß nicht, wie ich auf die Tabelle zugreifen kann und daraus die y-Werte auslesen kann. Wenn man den Wert für m für alle Tabellen hat, sollten die dann wieder in eine neue Tabelle gespeichert werden. In dieser sollten in der einen Spalte die Nummer der vorigen Tabelle stehen und in der anderen die Steigungen.

Vielen Dank schon mal!

P.S.: auf meinem Laptop läuft nicht Kubuntu, sonder Linux Mint..ich musste nur irgendetwas auswählen

Messung0.ksh (67 Bytes)
Download Messung0.ksh

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

Hi naka95,

erstmal herzlich willkommen hier auf dem Forum !

Grundsätzlich wirst Du ein Problem haben, wenn Du solche Kommawerte mit der Shell verarbeiten willst: die kann nämlich einzig und allein Integer-Zahlen !

Also mußt Du so oder so ein anderes Programm hinzunehmen, das Gleitkommazahlen kennt, am besten irgendeine höhere Sprache deines Vertrauens, oder auch einfach awk. Die können gleich den Formalkram mit erledigen.

Nehmen wir z.B. awk:

track@track:~$ awk '{if($1-xvor!=0) print "Steigung:", ($2-yvor)/($1-xvor); xvor=$1; yvor=$2}' Downloads/*.ksh
Steigung: 7.46341
Steigung: 4.25272
Steigung: 14.5889 

oder, den Einzeiler mal in Skript-Schreibweise:

1
2
3
4
    {   if ($1-xvor != 0)                                  # zum Schutz gegen Division durch 0
                print "Steigung:", ($2-yvor)/($1-xvor);
        xvor=$1;
        yvor=$2    }

Unabhängig von der Integer- Begrenzung wäre solche Berechnung mit der Shell auch rein formal umständlicher.

LG,

track

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17604

Wohnort: Berlin

Bitte solche Skripte - ich würde sagen bis zu ca. 100 Zeilen - nicht als Download/Anhang anbieten, sondern als Code einbetten, dass man es sieht:

1
2
3
4
5
#Weg	Kraft
0.0	0.0
25	186.5852134
40	250.3759729
65	615.0974208

Mit reinen Bashmitteln ist eine Lösung auch möglich, aber zugegeben ist sie nicht sehr elegant:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/bin/bash
arr=($(< weg-kraft.txt))
for i in {2..7..2}
do 
	# echo -n ${arr[i]}"   "
	x2=${arr[i+2]}
	x1=${arr[i]}
	y2=${arr[i+3]}
	y1=${arr[i+1]}
	# echo -n $x1 $x2 $y1 $y2"    "
	xd=$((${x2/.*/}-${x1/.*/}))
	yd=$((${y2/.*/}-${y1/.*/}))
    m=$((100*yd/xd))
    l=${#m}
    echo ${m:0:-2}.${m:l-2:l}
done

echo

for i in 2 4 6
do
    # echo "scale=5;(${arr[i+3]}-${arr[i+1]})/(${arr[i+2]}-${arr[i]})" 
    echo "scale=5;(${arr[i+3]}-${arr[i+1]})/(${arr[i+2]}-${arr[i]})" | bc 
done

for i in {2..7..2} iteriert von 2 bis 7 in 2er-Schritten. Bei größeren Zahlbereichen ist diese Schreibweise angemessen, aber hier sind es ja nur 3 Werte, daher ist for i in 2 5 7 ebenso gut und billiger zu schreiben wie leichter zu verstehen.

Die Hilfsvariablen x1, x2, y1, y2 dienen der Lesbarkeit. ${x2/.*/} schneidet von x2 alles hinter dem Punkt ab. Die Frage ist, ob man sich derartige Ungenauigkeiten leisten kann. Analoges gilt für die 3 anderen Variablen selbstverständlich. xd=$((foo-bar)) ist dann trivial zu verstehen, statt $((yd/xd)) habe ich 100*yd genommen, um 2 Nachkommastellen zu generieren. l=${#m} ist die Länge der Variablen m, echo ${m:0:-2}.${m:l-2:l} nimmt alles von m ausser den letzten 2 Stellen, einen Punkt und dann die letzten 2 Stellen von m.

Darunter die Rechnung an bc weitergereicht:

1
2
3
4
5
6
7
7.44
4.26
14.60

7.46340
4.25271
14.58885

Man sieht, die Ergebnisse liegen nicht weit voneinander. Man könnte mit der Bash auch mit den 7 Nachkommastellen rechnen, wenn man die 0.0 geschickt verartztet und es ansonsten immer mit 7 Nachkommastellen zu tun hat - man würde einfach den . weglöschen, weil (a*10000-b*10000)/(c*10000-d*10000) das gleiche ist wie (a-b)/(c-d) - in der Frage steht übrigens fälschlich (a-b)/c - d.

naka95

(Themenstarter)

Anmeldungsdatum:
9. Dezember 2015

Beiträge: 3

Vielen Dank schon mal euch beiden! Ich glaube es liegt aber noch ein kleines Missverständnis vor. Ich möchte nicht alle Steigungen zwischen den einzelnen Punkten aus der Tabelle, sondern aus jeder Tabelle die Steigung zwischen 25 und 40. Die anderen Tabellen sehen genauso aus, wie die obige, nur mit anderen y-Werten. Man müsste also nur auf y bei x=25 und y bei x=40 zugreifen und die berechneten Steigungen in eine neue Tabelle abspeichern.

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

Jetzt müsstest Du uns nur noch verraten, ob gelegentlich auch noch (uninterssante) Messwerte dazwischen vorkommen ...

Aber grundsätzlich kannst Du ja bei awk und Konsorten beliebige Zusatzbedingungen einbauen. (→ Stichwort "Muster" in der awk- Einführung)

Also in Deinem Fall vielleicht so:

1
2
3
4
/^25\t/ {   xvor=$1;
            yvor=$2    }

/^40\t/ {   print "Steigung in", FILENAME, ($2-yvor)/($1-xvor)    }

Als Einzeiler geschrieben, kannst Du damit alle Deine Dateien abklappern:

1
awk '/^25\t/ {xvor=$1; yvor=$2} /^40\t/ {print "Steigung in", FILENAME, ($2-yvor)/($1-xvor)}'  *.ksh   > ergebnisse.txt

Du solltest allerdings unbedingt die Doku, die ich Dir verlinkt habe lesen und nachvollziehen, was hier geschieht !
Es ist nämlich sehr wichtig, selber zu verstehen, was man da tut, damit man sich nicht irgendwas halbseidenes an Land zieht.

LG,

track

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17604

Wohnort: Berlin

naka95 schrieb:

Vielen Dank schon mal euch beiden! Ich glaube es liegt aber noch ein kleines Missverständnis vor. Ich möchte nicht alle Steigungen zwischen den einzelnen Punkten aus der Tabelle, sondern aus jeder Tabelle die Steigung zwischen 25 und 40. Die anderen Tabellen sehen genauso aus, wie die obige, nur mit anderen y-Werten. Man müsste also nur auf y bei x=25 und y bei x=40 zugreifen und die berechneten Steigungen in eine neue Tabelle abspeichern.

Aber Du schaffst es doch alleine den richtigen Startwert und die restlichen 3 analog zu dieser Schleife3:

1
2
3
4
5
for i in 2 4 6
do
    # echo "scale=5;(${arr[i+3]}-${arr[i+1]})/(${arr[i+2]}-${arr[i]})" 
    echo "scale=5;(${arr[i+3]}-${arr[i+1]})/(${arr[i+2]}-${arr[i]})" | bc 
done

zu finden, oder?

naka95

(Themenstarter)

Anmeldungsdatum:
9. Dezember 2015

Beiträge: 3

Vielen Dank, aber ich hab inzwischen rausgefunden wie es auch mit einem bash Skript funktioniert. Das war mir am liebsten, da kenn ich mich schon etwas mehr aus.

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17604

Wohnort: Berlin

Auf jeden Fall die Lösung für sich behalten - es könnte sonst jmd. nützen, der den Thread hier findet!

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13174

user_unknown schrieb:

Auf jeden Fall die Lösung für sich behalten - es könnte sonst jmd. nützen, der den Thread hier findet!

Das wäre schlimm. Am Ende könnte sich jemand kostenlos aufschlauen! 😲

Antworten |