staging.inyokaproject.org

komplizierte JSON mit jq zu einfacher JSON?

Status: Ungelöst | Ubuntu-Version: Server 18.04 (Bionic Beaver)
Antworten |

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11278

Ah, das Skript gibt da noch was anderes als json auf stdout aus - lösche mal die Zeile 45 mit dem print('#' * 10, p, '#' * 10), damit das nicht in der Ausgabedatei landet.

KingArtus

(Themenstarter)

Anmeldungsdatum:
6. August 2007

Beiträge: 581

habe diese zeile in deinem Script entfehrnt

1
   # print('#' * 10, p, '#' * 10)

dann schein es zu gehen.

KingArtus

(Themenstarter)

Anmeldungsdatum:
6. August 2007

Beiträge: 581

aber die Ausgabe muss ich in eine datei umleiten oder? also > neu_xyz.json oder?

KingArtus

(Themenstarter)

Anmeldungsdatum:
6. August 2007

Beiträge: 581

ja so geht es, nun muss ich nur nach die Variavle hinbekommen

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
{
    "id": "$f",
    "request.created_by.department.name": null,
    "request.created_by.department.site.name": null,
    "request.created_by.email_id": null,
    "request.created_by.name": "System",
    "request.created_time.display_value": "Feb 2, 2020 11:56 AM",
    "request.description": null,
    "request.group.name": null,
    "request.id": "71472",
    "request.requester.email_id": "hkn@css.de",
    "request.requester.name": "hkn",
    "request.status.name": "Open",
    "request.subject": "FEHLER:  TransferBelege",
    "request.technician.email_id": null,
    "request.technician.name": null
}

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11278

Alles eine Frage des richtigen Quotings - die Shell expandiert Variablen nur innerhalb von doppelten Anführungszeichen, nicht innerhalb von einfachen - also könnte der Aufruf z.B. so aussehen:

python3 /docs/script/transform2.py /docs/transform/in/$f.json -a "{\"id\": \"$f\"}" > /docs/transform/out/$f.json 

Das Skript kann die Datei gleichzeitig glätten und Dinge anhängen, d.h. es ist kein zweiter Durchlauf nötig, wenn man bereits alle nötigen Informationen hat.

KingArtus

(Themenstarter)

Anmeldungsdatum:
6. August 2007

Beiträge: 581

Danke, das scheint echt sper zu gehen...

ist echt ein Segen wenn man sowas so gut kann...

ich dank dir wirklich recht herzlich...

meinst du das geht auch, wenn ich den gesamten inhalt einer html in einer variablen speichere und dass dann mit

1
"{\"content\": \"$content\"}" >

einfüge?

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11278

Was genau willst du denn da genau machen? Einen HTTP-Request könnte man ja auch direkt mit dem requests Modul für Python3 (Paket python3-requests) erschlagen, dann kann man sich den Umweg über die Shell sparen:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#!/usr/bin/env python3
from argparse import ArgumentParser
from collections.abc import MutableMapping
import json
import sys

import requests

parser = ArgumentParser(description="flatten json object and add additional values")
parser.add_argument("json", metavar="JSON", nargs="+", help="json file(s) to process")
parser.add_argument("-a", "--add-json", metavar="ADD_JSON", action="append", default=[], help="add json objects to output")
parser.add_argument("-c", "--content-url", metavar="CONTENT_URL", help="add content key with text content of given url")
parser.add_argument("-k", "--filter-key", metavar="FILTER_KEY", action="append", default=[], help="add key to select from the flattened result")
args = parser.parse_args()

# add all keys you want to use to the following list:
keys = [
    'request.subject',
    'request.id',
    'request.requester.email_id',
    'request.requester.name',
    'request.created_time.display_value',
]
keys.extend(args.filter_key)


def flatten(d, parent_key='', sep='_'):
    items = []
    for k, v in d.items():
        new_key = parent_key + sep + k if parent_key else k
        if isinstance(v, MutableMapping):
            items.extend(flatten(v, new_key, sep=sep).items())
        else:
            items.append((new_key, v))
    return dict(items)

addition_dict = {}

for addition in args.add_json:
    try:
        addition_dict.update(json.loads(addition))
    except json.JSONDecodeError:
       print("invalid json:", addition, file=sys.stderr)

for p in args.json:
    print('#' * 10, p, '#' * 10, file=sys.stderr)
    with open(p) as f:
        content = json.load(f)
    flattened = flatten(content, sep='.')
    result = {k: flattened.get(k) for k in keys}
    if args.content_url:
        r = requests.get(args.content_url)
        try:
            r.raise_for_status()
        except Exception as e:
            print("Could not retrieve url", args.content_url, e, file=sys.stderr)
        else:
            result['content'] = r.text
    result.update(addition_dict)
    print(json.dumps(result, sort_keys=True, indent=4, separators=(',', ': ')))

Damit könnte man dann sowas machen:

python3 /docs/script/transform2.py /docs/transform/in/$f.json -a "{\"id\": \"$f\"}" -c "http://example.com" > /docs/transform/out/$f.json  

KingArtus

(Themenstarter)

Anmeldungsdatum:
6. August 2007

Beiträge: 581

Also ich will aus einem Ticketsysem (blöd organisiert) alle infos über die API abrufen und eintragen...

leider kjann ich nicht alle infos zusammen abrufen sondern haben eine abfrage für einige infos, wieder eine anfrage für otizen und eine für Kommentare, und der Schriftverkehr lässt sich gar nicht abrufen über die api, s´ondern nur über eine local liegende HTML datei.

das will ich alles in die JSON pumpen und an eine Suchmaschine übergeben. um dann anschließend erfolgreich suchen zu können..

KingArtus

(Themenstarter)

Anmeldungsdatum:
6. August 2007

Beiträge: 581

und dass alles obgleich ich eine Nulpe im programmieren bin

KingArtus

(Themenstarter)

Anmeldungsdatum:
6. August 2007

Beiträge: 581

interessant wird es auch beim Abruf von den notizen, da das json da dann anders aussieht.. noch nicht probiert was mit deinem script dann pssiert..

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

{
    "operation": {
        "result": {
            "message": "Notes retreived properly",
            "status": "Success"
        },
        "Details": [
            {
                "notesid": 176702,
                "NOTESUSERID": "118802",
                "NOTESTEXT": "<div>Sweethome 3d installiert<br /></div><div><br /></div><div>Log Datei kopiert<br /></div>",
                "ISPUBLIC": "false",
                "USERNAME": "dgge, Jghmdgmhg",
                "NOTESDATE": "1580111062477"
            },
            {
                "notesid": 176516,
                "NOTESUSERID": "13805",
                "NOTESTEXT": "<div>Programm runtergeladen und Jörg zur Verfügung gestellt; Installation durch Jörg, da er am Montag das NB von Hr. Kolvenbach bekommt<br /></div>",
                "ISPUBLIC": "false",
                "USERNAME": "Ho, Sha",
                "NOTESDATE": "1579875705490"
            }
        ]
    }
}

hier habe ich ja 2 oder 3 oder 50 mal "notesid" also wenn ich da eingebe:

operation.result.Details.notesid

kommt ja mehrt als eine antwort und wie ist das dann zu zu ordnen? vortlaufenden Nummer? oder array? wie macht man das? am besten?

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11278

KingArtus schrieb:

und dass alles obgleich ich eine Nulpe im programmieren bin

Das muss ja kein Dauerzustand sein 😉

Versuch mal den kompletten Ablauf zu beschreiben, der nötig ist, um an die Daten zu kommen, wie API-Aufrufe aussehen sollen (schon mal geschaut, ob es für die API des Ticket-Systems fertige Bibliotheken gibt?) und wie Beispiele für die Daten aussehen, die man zurück bekommt.

KingArtus schrieb:

kommt ja mehrt als eine antwort und wie ist das dann zu zu ordnen? vortlaufenden Nummer? oder array? wie macht man das? am besten?

Als erstes muss man sich überlegen, was man mit den Daten vorhat und davon würde ich abhängig machen, wie man sie aufbereitet. Im JSON sind die Details ein Array aus Objekten, was man ja durchaus beibehalten kann, wenn man das Problem mit einer Sprache wie Python3 angeht und sich die Verrenkungen mit jq erspart.

Antworten |