[bash] json, curl, Arrays und Variablen. Ich werde wahnsinnig

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
dmant
Beiträge: 251
Registriert: 09.10.2017 10:28:29

[bash] json, curl, Arrays und Variablen. Ich werde wahnsinnig

Beitrag von dmant » 18.02.2018 10:52:42

Morgen allerseits,

seit gestern versuche ich einfach nur ein json array in eine mysql Datenbank zu schreiben, das ganze in einer bash schleife mit delay etc. Naja das ist erstmal nebensächlich, also einem am Tag aktualisiert (Mo-Fr) die europäische Zentralbank die Kurse. Eine Seite mit häufigeren Kursaktualisierungen habe ich nicht finden können (vll kennt ja jemand eine).

Nunja zunächst rufe ich die Seite mittels curl auf und erhalte die XML Seite. Perfekt. Diese speichere ich dann erstmal unter curltemp.txt

Mittels

xml2json curltemp.txt curltemp.json

Wandel ich diese dann in ein json array um.

Code: Alles auswählen

#!/bin/bash

curl "http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml" > curltemp.xml

xml2json curltemp.xml curltemp.json && rm curltemp.xml

DATUM=`cat curltemp.json | jq '.[].Cube.Cube.time'`
DATAARRAY=`cat curltemp.json | jq ' [].Cube.Cube.Cube'`

for i in ${DATAARRAY[0]}
do
    echo ${i[*]}
done
An das Datum komme ich noch ran aber an die weiteren Daten nicht mehr.

Das json array sieht wie folgt aus https://nopaste.dmant.ovh/?v=ojahTh7naik1

Ich bekomme in

$i

gibt mir immer nur das ganze Array aus, keinen key o.ä. womit ich tiefer ins array schauen könnte.

eggy
Beiträge: 3331
Registriert: 10.05.2008 11:23:50

Re: [bash] json, curl, Arrays und Variablen. Ich werde wahnsinnig

Beitrag von eggy » 18.02.2018 11:13:57

Geht sowohl schöner als auch eleganter, aber nen awk Schnellschuss sähe so aus:

Code: Alles auswählen

awk  'BEGIN{FS=":"} {gsub(",","")} /time/{gsub(""",""); print $2} /currency/{gsub(""",""); printf $2} /rate[^s]/{gsub(""",""); print $2}'   daten.txt  
Allerdings wäre ich sehr vorsichtig dabei Daten aus externen Quellen ungeprüft weiterzuverarbeiten
"Little Bobby Tables lässt grüßen" ( https://xkcd.com/327/ )

breakthewall
Beiträge: 507
Registriert: 30.12.2016 23:48:51

Re: [bash] json, curl, Arrays und Variablen. Ich werde wahnsinnig

Beitrag von breakthewall » 18.02.2018 11:56:53

dmant hat geschrieben: ↑ zum Beitrag ↑
18.02.2018 10:52:42

Code: Alles auswählen

DATAARRAY=`cat curltemp.json | jq ' [].Cube.Cube.Cube'`
Dein Problem hier ist, dass Du ein Array durchsuchen willst, ohne jemals ein Array angelegt zu haben.

Ein Array hat dieses Format:

Code: Alles auswählen

DATAARRAY=($(cat curltemp.json | jq ' [].Cube.Cube.Cube'))
Idealerweise sollte man Backticks nicht länger verwenden, und stattdessen auf das moderne $(....) Konstrukt setzen. Die for-Schleife kannst prinzipiell auch weglassen, da man so kein Array als Ganzes einlesen, und mittels echo nur bestimmte Elemente anzeigen lassen kann. Daher nur mit echo und entsprechenden Zahlen bzw. Positionen arbeiten.

dmant
Beiträge: 251
Registriert: 09.10.2017 10:28:29

Re: [bash] json, curl, Arrays und Variablen. Ich werde wahnsinnig

Beitrag von dmant » 18.02.2018 13:13:18

Ich komme da nicht dran. Immer error index array und kA.

Naja, ich versuchte somit einen neuen Ansatz und konnte schonwieder durchdrehen.

Code: Alles auswählen

#!/bin/bash

curl "http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml" > curltemp.xml

IFS=$'\n' lines=( $( cat curltemp.xml))

for index in ${!lines[*]}
do
    if [ $index -eq 6 ]
    then
      DATUM=${lines[$index]};
    fi

    if [ $index -gt 7 ] && [ $index -lt 40 ]
    then
      echo ${lines[$index]} | tr -cd '[A-Z ]'; # Waehrung
      echo ${lines[$index]} | tr -cd '[.0-9]'; # Kurs
    fi

done

rm curltemp.xml
Ich bekomme so die Waehrung und den Kurs ausgegeben. Super dachte ich mir, allerdings kann ich die Daten nicht weiter verarbeiten. Ich kann sie nur ausgeben, sobald ich versuche das ganze in eine Variable zu schreiben ist die Variable einfach nur leer, ich habe mit ( in " usw versucht. Die Variable bleibt einfach leer.

Code: Alles auswählen

....
KURS=${lines[$index]} | tr -cd '[A_Z]'
....
$KURS bleibt hier einfach leer. Aber das echo in der Schleife funktioniert 1A. Ich werde noch verrückt. Auf der Bash geht es aucj, ich script nicht. aaarrrggg

breakthewall
Beiträge: 507
Registriert: 30.12.2016 23:48:51

Re: [bash] json, curl, Arrays und Variablen. Ich werde wahnsinnig

Beitrag von breakthewall » 18.02.2018 14:12:27

Die Variable ist auch Murks in dieser Form. :wink:

Das hier wäre besser:

Code: Alles auswählen

KURS="$(echo ${lines[$index]} | tr -cd '[A-Z]')"
Ich würde Dir das Programm shellcheck nahelegen, womit solche als auch schwerwiegende Fehler direkt sehen würdest, mit nützlichen Lösungsvorschlägen. Hilft insbesondere dann, wenn man mal den Wald vor lauter Bäumen nicht sieht. :wink:

owl102

Re: [bash] json, curl, Arrays und Variablen. Ich werde wahnsinnig

Beitrag von owl102 » 18.02.2018 14:57:57

breakthewall hat geschrieben: ↑ zum Beitrag ↑
18.02.2018 14:12:27
Ich würde Dir das Programm shellcheck nahelegen
Dem schließe ich mich an. Außerdem empfehle ich den sehr kompakten aber IMHO auch sehr guten Bash Guide: http://mywiki.wooledge.org/BashGuide

Dort gibt es auch eine FAQ für die häufigsten Problemstellungen: http://mywiki.wooledge.org/BashFAQ

BTW: Eine Datei kann man in bash auch so in ein Zeilen-Array lesen:

Code: Alles auswählen

mapfile -t lines <curltemp.xml
Zuletzt geändert von owl102 am 18.02.2018 19:06:15, insgesamt 1-mal geändert.

rendegast
Beiträge: 15041
Registriert: 27.02.2006 16:50:33
Lizenz eigener Beiträge: MIT Lizenz

Re: [bash] json, curl, Arrays und Variablen. Ich werde wahnsinnig

Beitrag von rendegast » 18.02.2018 18:50:37

Code: Alles auswählen

DATUM=`cat curltemp.json | jq '.[].Cube.Cube.time'`
DATAARRAY=`cat curltemp.json | jq ' [].Cube.Cube.Cube'`
Im Argument des zweiten 'jq' fehlt der anfängliche Punkt.
mfg rendegast
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")

dmant
Beiträge: 251
Registriert: 09.10.2017 10:28:29

Re: [bash] json, curl, Arrays und Variablen. Ich werde wahnsinnig

Beitrag von dmant » 18.02.2018 20:34:17

Ich habe es nun hinbekommen und folgendermaßen gelöst:

Code: Alles auswählen

#!/bin/bash

MYSQL_DATABASE="XXX"
MYSQL_USER="XXX"
MYSQL_PASSWORD="XXX"

while true
do

CHECK_EXIST=$(echo "SELECT * FROM waehrungskurse WHERE datum > (NOW() - INTERVAL 60 MINUTE)" | mysql $MYSQL_DATABASE -u $MYSQL_USER -p$MYSQL_PASSWORD)

if [ -z "$CHECK_EXIST" ]
then

  curl "http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml" -o curltemp.xml 1&> /dev/null
  IFS=$'\n' lines=( $( cat curltemp.xml))

  echo "INSERT INTO waehrungskurse (ID, datum) VALUES (NULL, NOW())" | mysql $MYSQL_DATABASE -u $MYSQL_USER -p$MYSQL_PASSWORD
  INSERTID=$(echo "SELECT ID FROM waehrungskurse ORDER BY ID DESC LIMIT 1" | mysql $MYSQL_DATABASE -u $MYSQL_USER -p$MYSQL_PASSWORD)
  INSERTID=${INSERTID:3}

  for index in ${!lines[*]}
  do
      if [ $index -eq 7 ]
      then
        DATUM=$(echo ${lines[$index]});
        DATUM=$(echo "$DATUM" | tr -cd '[0-9-]');
        echo "UPDATE waehrungskurse SET bankdatum = '$DATUM', EUR = '1.00' WHERE ID = $INSERTID" | mysql $MYSQL_DATABASE -u $MYSQL_USER -p$MYSQL_PASSWORD
      fi
      if [ $index -gt 7 ] && [ $index -lt 40 ]
      then
        TEMP=${lines[$index]}
        WAEHRUNG=$(echo "$TEMP" | tr -cd '[A-Z ]'); # Waehrung
        WAEHRUNG=${WAEHRUNG:2}
        KURS=$(echo "$TEMP" | tr -cd '[.0-9]'); # Kurs
        echo "UPDATE waehrungskurse SET $WAEHRUNG = '$KURS' WHERE ID = $INSERTID" | mysql $MYSQL_DATABASE -u $MYSQL_USER -p$MYSQL_PASSWORD
      fi
done
rm curltemp.xml
fi
sleep 30m
done
Danke für eure Hilfen.

Antworten