IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Shell et commandes GNU Discussion :

Traitement de données JSON


Sujet :

Shell et commandes GNU

  1. #1
    Membre éclairé
    Inscrit en
    Octobre 2005
    Messages
    908
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 908
    Par défaut Traitement de données JSON
    Bonjour,
    je récupère des datas JSON (devices et sessions) via 2 commandes curl dans un script bash :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    $ curl https://serveur/api/devices | jq
    [
    	{
    		"device_name": "AAAA",
    		"host": "172.20.1.1"
    	},
    	{
    		"device_name": "BBBB",
    		"host": "172.20.1.2"
    	},
    	{
    		"device_name": "CCCC",
    		"host": "172.20.1.3"
    	}
    ]
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    $ curl https://serveur/api/sessions| jq
    [
    	{
    		"group_name": "GROUP_A",
    		"session": {
    			"accounts": [
    				{
    					"device": "AAAA",
    					"service": "SSH"
    				},
    				{
    					"device": "CCCC",
    					"service": "RDP"
    				}
    			],
    			"scenario_accounts": [],
    			"account_mappings": [
    				{
    					"device": "BBBB",
    					"service": "RDP"
    				},
    				{
    					"device": "CCCC",
    					"service": "RDP"
    				}
    			],
    			"interactive_logins": [
    				{
    					"device": "BBBB",
    					"service": "SSH"
    				}
    			]
    		}
    	},
    	{
    		"group_name": "GROUP_B",
    		"session": {
    			"accounts": [],
    			"scenario_accounts": [],
    			"account_mappings": [
    				{
    					"device": "AAAA",
    					"service": "RDP"
    				}
    			],
    			"interactive_logins": []
    		}
    	}
    ]
    Mon but est de comptabiliser les sessions par device et d'obtenir ce tableau :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    [
    	"AAAA" : [
    		"host": "172.20.1.1",
    		"accounts": 		1,
    		"scenario_accounts": 	0,
    		"account_mappings": 	1,
    		"interactive_logins": 	0
    	],
    	"BBBB" : [
    		"host": "172.20.1.2",
    		"accounts": 		1,
    		"scenario_accounts": 	0,
    		"account_mappings": 	0,
    		"interactive_logins": 	1
    	],
    	"CCCC" : [
    		"host": "172.20.1.3",
    		"accounts": 		1,
    		"scenario_accounts": 	0,
    		"account_mappings": 	1,
    		"interactive_logins": 	0
    	]
    ]
    Première étape : construction du tableau final

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    devices=$(curl https://serveur/api/devices | jq)
    readarray -t aDevices <<< $devices
    declare -A allDevices=()
    for device in "${aDevices[@]}"; do
    	declare -A aDevice
    	name=$(jq '.device_name' <<< "$device")
    	host=$(jq '.host' <<< "$device")
    	aDevice[host]=$host
    	aDevice[accounts]=0
    	aDevice[scenario_accounts]=0
    	aDevice[account_mappings]=0
    	aDevice[interactive_logins]=0
    	allDevices[$name]=aDevice
    done
    Est-ce que c'est une bonne méthode pour commencer ?
    Je dis ça... parce que je ne vois pas comment faire la suite
    parcourir le tableau de sessions est trop complexe pour moi... Y aurait-il une star du JSON+JQ+ARRAY ici ? un p'tit coup de pouce svp.
    merci d'avance

  2. #2
    Membre actif
    Homme Profil pro
    pas tout le temps.
    Inscrit en
    Janvier 2017
    Messages
    50
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : pas tout le temps.

    Informations forums :
    Inscription : Janvier 2017
    Messages : 50
    Par défaut
    ce que je vais faire, c'est
    • aller à la casse auto
    • acheter une caisse, et un moteur
    • jeter le moteur dans le coffre
    • aller voir un garagiste, et lui dire ça :
      Est-ce que c'est une bonne méthode pour commencer ?
      Je dis ça... parce que je ne vois pas comment faire la suite
    • ensuite, je vais revenir ici et vous donner sa réponse.

  3. #3
    Expert confirmé Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 293
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 293
    Par défaut
    Bonjour

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $ jq -r '.[].session | to_entries | .[] | .key+";"+.value[].device' sessions.json 
    accounts;AAAA
    accounts;CCCC
    account_mappings;BBBB
    account_mappings;CCCC
    interactive_logins;BBBB
    account_mappings;AAAA
    Il n'y a plus qu'à compter. Avec awk par exemple.

  4. #4
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 664
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 664
    Par défaut
    petite remarque sur le tableau de sortie : s'il doit être au format JSON, alors il n'est pas valide (un tableau JSON ne peut pas contenir de couple clé/valeur).
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  5. #5
    Membre éclairé
    Inscrit en
    Octobre 2005
    Messages
    908
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 908
    Par défaut
    Bonjour à tous
    et merci Flodelarab et N_BaH pour votre aide.

    @Flodelarab : effectivement je pourrais m'en sortir de cette manière mais je perd les sous totaux par groupe (AAAA, ...)
    (j'avais jamais vu to_entries | .[] | .key+";"+.value[] )

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    awk '
    BEGIN {
    	FS=";"
    } 
    {
    	type=$1
    	device=$2
    	if(devices[device][type] == "") {
    		devices[device][type]=1
    	} else {
    		devices[device][type]++
    	}
    }
    END {
    	for (d in devices) {
    		total=devices[d]["accounts"]+devices[d]["account_mappings"]+devices[d]["interactive_logins"]+devices[d]["scenario_accounts"]
    		print d","devices[d]["accounts"]","devices[d]["account_mappings"]","devices[d]["interactive_logins"]","devices[d]["scenario_accounts"]","total
    	}
    }' <<< $jq1
    y a moyen de récupérer le groupe en + ?

  6. #6
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 664
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 664
    Par défaut
    que c'est compliqué tortueux !

    KISS!
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    awk -F';' '{ar[$2][$1]++}END{PROCINFO["sorted_in"]="@ind_str_asc"; for(i in ar){print i; for(y in ar[i])print "\t",y,ar[i][y]}}' < <(jq -r '.[].session | to_entries | .[] | .key+";"+.value[].device' /tmp/sessions.json)
    AAAA
             account_mappings 1
             accounts 1
    BBBB
             account_mappings 1
             interactive_logins 1
    CCCC
             account_mappings 2
             accounts 1
    --
    CCCC account_mappings = 2 parce que j'ai modifié le fichier sessions.json pour vérifier le calcul
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  7. #7
    Membre éclairé
    Inscrit en
    Octobre 2005
    Messages
    908
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 908
    Par défaut
    c'est propre c'est beau....
    merci !

    dernière question et j'arrête de vous embêter...
    Admettons que j'ai un device DDDD (dans device.json) sans aucune session (pas de référence de DDDD dans sessions.json)
    Comment faire pour l'avoir en sortie avec une quantité de 0 ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    AAAA
             account_mappings 1
             accounts 1
    BBBB
             account_mappings 1
             interactive_logins 1
    CCCC
             account_mappings 2
             accounts 1
    DDDD

  8. #8
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 664
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 664
    Par défaut
    il apparaît dans api/devices ?
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  9. #9
    Membre éclairé
    Inscrit en
    Octobre 2005
    Messages
    908
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 908
    Par défaut
    oui

  10. #10
    Expert confirmé Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 293
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 293
    Par défaut
    Pour que tout le monde soit heureux :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    jq 'map( .group_name as $gr| .session | to_entries | map({groupe: $gr, categorie:.key, device:.value[].device})) |add'
    Et pour que les amateurs de csv ne soient pas en reste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $ jq -r 'map( .group_name as $gr| .session | to_entries | map({groupe: $gr, categorie:.key, device:.value[].device})) |add  | .[] |map(scalars)|@csv' sessions.json 
    "GROUP_A","accounts","AAAA"
    "GROUP_A","accounts","CCCC"
    "GROUP_A","account_mappings","BBBB"
    "GROUP_A","account_mappings","CCCC"
    "GROUP_A","interactive_logins","BBBB"
    "GROUP_B","account_mappings","AAAA"

  11. #11
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 664
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 664
    Par défaut
    pourquoi serait-on heureux ?
    il n'a pas été dit que le group_name est une donnée pertinente.
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  12. #12
    Expert confirmé Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 293
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 293
    Par défaut
    Toi, parce que tu veux rester dans un format JSON; et Tchupacabra qui demande "y a moyen de récupérer le groupe en + ? ".

    Et puisqu'on pinaille, je remarque que, dans ton excellente commande, le < dans awk ... < <(jq ...) est superflu.

  13. #13
    Expert confirmé Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 293
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 293
    Par défaut
    Après, group_by pour regrouper à loisir et length pour compter.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $ jq -r 'map( .group_name as $gr| .session | to_entries | map({groupe: $gr, categorie:.key, device:.value[].device})) |add |group_by(.device+.categorie+.groupe) | .[] | length as $l | [.[].categorie,.[].device,.[].groupe,$l]|unique|@csv' sessions.json 
    1,"AAAA","GROUP_B","account_mappings"
    1,"AAAA","GROUP_A","accounts"
    1,"BBBB","GROUP_A","account_mappings"
    1,"BBBB","GROUP_A","interactive_logins"
    1,"CCCC","GROUP_A","account_mappings"
    2,"CCCC","GROUP_A","accounts"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ jq -r 'map( .group_name as $gr| .session | to_entries | map({groupe: $gr, categorie:.key, device:.value[].device})) |add |group_by(.device) | .[] | length as $l | [.[].device,$l]|unique|@csv' sessions.json 
    2,"AAAA"
    2,"BBBB"
    3,"CCCC"

  14. #14
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 664
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 664
    Par défaut
    je crois que Tchupacabra s'est trompé d'expression
    je perd les sous totaux par groupe (AAAA, ...)
    puisque les groupes, c'est group_A, group_B..., quand AAAA, BBBB ... sont les devices.

    à Tchupacabra d'expliciter ce qu'il veut.
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

Discussions similaires

  1. Réponses: 4
    Dernier message: 18/02/2017, 09h49
  2. [OpenLayers] Récupération et traitement de données JSON
    Par ineszarka dans le forum Bibliothèques & Frameworks
    Réponses: 3
    Dernier message: 25/06/2016, 09h00
  3. Traitement de données JSON via websocket
    Par glbaa dans le forum Général JavaScript
    Réponses: 11
    Dernier message: 15/05/2013, 21h04
  4. traitement des données avant envoie dans MySQL
    Par italiasky dans le forum SQL Procédural
    Réponses: 13
    Dernier message: 07/02/2006, 22h50
  5. Programmation pour traitement de données
    Par benbois dans le forum Langages de programmation
    Réponses: 16
    Dernier message: 19/10/2005, 17h01

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo