Агрегирование результатов JSON с помощью JQ и передача аргумента в код python - PullRequest
0 голосов
/ 07 мая 2020

Мне нужно собрать несколько JSON результатов с сайта. Поскольку на сайте есть ограничение параллелизма запросов и время ожидания запросов, временные рамки для запросов должны быть разделены. Итак, у меня осталось JSON следующим образом:

{
      "results": [
          [
              {
                  "field": "AccountId",
                  "value": "11352"
              },
              {
                  "field": "number_of_requests",
                  "value": "241398"
              }
          ],
          [
              {
                  "field": "AccountId",
                  "value": "74923"
              },
              {
                  "field": "number_of_requests",
                  "value": "238566"
              }
          ]
          ],
"statistics": {
          "recordsMatched": 502870.0,
          "recordsScanned": 165908292.0,
          "bytesScanned": 744173091162.0
      },
      "status": "Complete"
}
{
      "results": [
          [
              {
                  "field": "AccountId",
                  "value": "11352"
              },
              {
                  "field": "number_of_requests",
                  "value": "185096"
              }
           ]
          ],
"statistics": {
          "recordsMatched": 502870.0,
          "recordsScanned": 165908292.0,
          "bytesScanned": 744173091162.0
      },
      "status": "Complete"
  }

Моя цель - агрегировать результаты, а также идентификатор учетной записи фида в качестве аргумента кода python, который выводит строку. Код python выглядит следующим образом:

python check_account.py 11352

Internal

python check_account.py 74923

External

Итак, мой желаемый результат для добавления в файл:

AccountID: Количество запросов: Тип

11352: 426494: Внутренний

74923: 238566 : External

На данный момент у меня есть код python с API, который вызывает соответствующие функции и выводит Internal или External в качестве вывода.

И следующий скрипт в bash используя jq:

#!/bin/zsh

ResultsDir=$1

list=$(jq -nr '
[inputs | .results[] | map( { (.field) : .value} ) | add]
| group_by(.AccountId)
| map([.[0].AccountId, (map(.number_of_requests|tonumber) | add)])
| sort_by(.[1]) | reverse
| "\(.[]) " ' $ResultsDir)
echo "Results saved in file query-results"
echo "ACCOUNT ID : #_OF_REQUESTS" > $ResultsDir/query-results
echo "$list" >> $ResultsDir/query-results

Существует способ сделать это в самом коде python, но мне было интересно, есть ли способ использовать сценарий python выше как код python используется во многих других функциях.

1 Ответ

0 голосов
/ 09 мая 2020

Если я правильно понял вопрос, вы хотите вызвать python сценарий check_account.py из написанного вами сценария оболочки. Это сделано потому, что check_account.py используется в нескольких местах, и вы не хотите изменять его функциональность.

Команда jq, которую вы написали в приведенном выше сценарии, может получить AccountId и агрегированное значение число_запросов. Теперь вы хотите вызвать check_account.py с AccountId в качестве параметра. Приведенный ниже сценарий является его реализацией.

#!/bin/bash

ResultsDir=$1
accountIds=`cat input.js | jq -nr '[inputs | .results[] | map( { (.field) : .value} ) | add] | group_by(.AccountId)| map([.[0].AccountId, (map(.number_of_requests|tonumber) | add)])| sort_by(.[1]) | reverse| "\(.[]) "' | jq -r .[0]`
echo $accountIds
numberOfRequests=`cat input.js | jq -nr '[inputs | .results[] | map( { (.field) : .value} ) | add] | group_by(.AccountId)| map([.[0].AccountId, (map(.number_of_requests|tonumber) | add)])| sort_by(.[1]) | reverse| "\(.[]) "' | jq -r .[1]`
echo "Results saved in file query-results"
echo "AccountID : Number of Requests : Type" > $ResultsDir/query-results
echo "$list"
echo "Will call the check_account.py now"
accountIdsArray=($(echo $accountIds | tr " " "\n")) # to convert into array so that i can loop on the array
numberOfRequestsArray=($(echo $numberOfRequests | tr " " "\n"))
len=${#accountIdsArray[@]} # to find the length of the array
echo $len
  for (( i=0; i<=$((len-1)); i++ )); do 
       value=${accountIdsArray[$i]} 
       echo "index $i - value $value"
       account=$(python check_account.py $value)
       echo $value ${numberOfRequestsArray[$i]} $account >> $ResultsDir/query-results
  done

У меня нет реализации check_account.py. Итак, я написал следующий сценарий python для проверки моего сценария оболочки.

#!/usr/bin/env python
import sys
a = int(sys.argv[1])

def my_function():
    if a == 11352:
        print("Internal")
    if a == 74923:
        print("External")

if __name__ == "__main__":
    my_function()

Здесь следует отметить одну важную вещь: сценарий оболочки по умолчанию захватывает «стандартный вывод» (STDOUT) процесса Python. Чтобы зафиксировать это, вам просто нужно использовать $ (). Внутри скобок вы можете написать свою команду для вызова сценария python.

Выполнив сценарий оболочки, подобный этому

./final-test.sh /Users/ajay/Desktop/

, я смог получить файл с именем query-results . Содержимое результатов запроса файла следующее:

AccountID : Number of Requests : Type
11352 : 426494 : Internal
74923 : 238566 : External

Надеюсь, это поможет понять, как вызвать python сценарий из сценария оболочки и зафиксировать его результат в сценарии оболочки.

...