Ansible выводить версию пакета с использованием jq - PullRequest
2 голосов
/ 14 февраля 2020

У меня ниже json вывод ansible, я хочу проанализировать этот файл, используя jq. Я хочу сопоставить имя пакета GeoIP и номер версии печати. ​​

Как я могу использовать jq, чтобы получить этот номер версии для соответствия имени пакета? выглядит как вывод

"GeoIP","1.5.0"

выборка ansible вывод

{
    "ansible_facts.packages": {
        "GConf2": [
            {
                "arch": "x86_64",
                "epoch": null,
                "name": "GConf2",
                "release": "8.el7",
                "source": "rpm",
                "version": "3.2.6"
            }
        ],
        "GeoIP": [
            {
                "arch": "x86_64",
                "epoch": null,
                "name": "GeoIP",
                "release": "14.el7",
                "source": "rpm",
                "version": "1.5.0"
            }
        ],
        "ImageMagick": [
            {
                "arch": "x86_64",
                "epoch": null,
                "name": "ImageMagick",
                "release": "18.el7",
                "source": "rpm",
                "version": "6.7.8.9"
            }
        ],
    }
}

Ответы [ 3 ]

1 голос
/ 14 февраля 2020

Сначала сделайте источник действительным json, удалив запятую в строке с третьей по последнюю.

После этого мы можем начать с конца и вернуться обратно. Желаемый результат может быть получен с использованием формата @csv jq. Это, в свою очередь, требует, чтобы выходные данные были в массиве. (См. Раздел руководства под названием «Форматирование строк и экранирование».) Поэтому нам нужно, чтобы данные выглядели так.

jq -r '["GeoIP","1.5.0"] | @csv'

Один из способов сделать это - поместить каждый элемент в свой собственный массив и добавить массивы вместе. (См. раздел под названием «Добавление».)

jq -r '["GeoIP"] + [.[] | .GeoIP[].version] | @csv'

Поскольку map(x) определяется как [.[] | x], вы можете сказать это вместо этого.

jq -r '["GeoIP"] + map(.GeoIP[].version) | @csv'

Вы можете использовать переменную, чтобы указать желаемое имя пакета следующим образом.

jq -r --arg "package" "GeoIP" '[$package] + map(.[$package][].version) | @csv'

Обновление

В моем исходном решении есть ненужные шаги. Массив можно сделать так:

jq -r '[ "GeoIP", .[].GeoIP[].version ] | @csv'

Или, используя переменную

jq -r --arg "package" "GeoIP" '[$package,(.[] | .[$package][].version)]| @csv'
0 голосов
/ 14 февраля 2020

Q: "Как я могу использовать jq, чтобы получить номер версии для соответствующего имени пакета?"

A: Попробуйте приведенный ниже скрипт

$ cat print-version.sh
#!/bin/sh
cat output.json | jq ".ansible_facts.packages.$1 | .[].version"

Например

$ print-version.sh GeoIP
"1.5.0"


Улучшенная версия скрипта

Цитирование комментария: "Using the shell's string interpolation as done here is risky and generally regarded as an "anti-pattern". – peak"

The улучшенный скрипт ниже выполняет работу

$ cat print-version.sh
#!/bin/sh
cat output.json | jq ".ansible_facts.packages.$1[].version"


вывод. json
{
    "ansible_facts": {
        "packages": {
            "GConf2": [
                {
                    "arch": "x86_64",
                    "epoch": null,
                    "name": "GConf2",
                    "release": "8.el7",
                    "source": "rpm",
                    "version": "3.2.6"
                }
            ],
            "GeoIP": [
                {
                    "arch": "x86_64",
                    "epoch": null,
                    "name": "GeoIP",
                    "release": "14.el7",
                    "source": "rpm",
                    "version": "1.5.0"
                }
            ],
            "ImageMagick": [
                {
                    "arch": "x86_64",
                    "epoch": null,
                    "name": "ImageMagick",
                    "release": "18.el7",
                    "source": "rpm",
                    "version": "6.7.8.9"
                }
            ]
        }
    }
}
0 голосов
/ 14 февраля 2020

Я предполагаю, что вы хотите получить al oop для всех атрибутов значений ключа в ansible_facts.packages, поэтому рекомендуется использовать bash l oop для его итерации. также пример содержимого json, который вы предоставили, не компилируется, я удалил запятую 3 строки с конца.

вам нужен один jq, чтобы получить все ключи ansible_facts.packages, а затем в каждой итерации, чтобы получить версию данного ключа (пакета)

, чтобы получить все ключи:

[http_offline@greenhat-30 tmp]$ cat file.json | jq '."ansible_facts.packages" | keys[]'
"GConf2"
"GeoIP"
"ImageMagick"
[http_offline@greenhat-30 tmp]$ 

l oop:

for package in `cat file.json | jq '."ansible_facts.packages" | keys[]'`
do
VERSION=`cat file.json | jq ".\"ansible_facts.packages\".$package[0].version"`
echo "$package,$VERSION"
done

примерный прогон:

[http_offline@greenhat-30 tmp]$ for package in `cat file.json | jq '."ansible_facts.packages" | keys[]'`
> do
> VERSION=`cat file.json | jq ".\"ansible_facts.packages\".$package[0].version"`
> echo "$package,$VERSION"
> done
"GConf2","3.2.6"
"GeoIP","1.5.0"
"ImageMagick","6.7.8.9"
[http_offline@greenhat-30 tmp]$ 

надеюсь, это поможет.

...