Извлечь 2 поля из строки с поиском - PullRequest
2 голосов
/ 04 марта 2020

У меня есть файл с несколькими строками данных. Поля не всегда находятся в одной позиции / столбце. Я хочу найти 2 строки, а затем показать только поле и данные, которые следуют. Например:

{"id":"1111","name":"2222","versionCurrent":"3333","hwVersion":"4444"}

{"id":"5555","name":"6666","hwVersion":"7777"}

Я хотел бы вернуть следующее:

"id":"1111","hwVersion":"4444"

"id":"5555","hwVersion":"7777"

Я борюсь, потому что данные не всегда находятся в одной и той же позиции, поэтому я не могу выбрать номер столбца. Я чувствую, что мне нужно искать "id" и "hwVersion". Любая помощь приветствуется.

Ответы [ 2 ]

0 голосов
/ 04 марта 2020

Полностью согласен с @KamilCuk. В частности,

jq -c '{id: .id, hwVersion: .hwVersion}' <<< '{"id":"1111","name":"2222","versionCurrent":"3333","hwVersion":"4444"}'

Выходы:

{"id":"1111","hwVersion":"4444"}

Не совсем указанный вывод, но действительный JSON

Более конкретно, ваш ввод, вероятно, должен быть обработан запись за записью, и я предполагаю, что вывод двух столбцов с "id" и "hwVersion" будет еще проще проанализировать:

cat << EOF | jq -j '"\(.id)\t\(.hwVersion)\n"'
{"id":"1111","name":"2222","versionCurrent":"3333","hwVersion":"4444"}
{"id":"5555","name":"6666","hwVersion":"7777"}
EOF

Выходы:

1111    4444
5555    7777
0 голосов
/ 04 марта 2020

Поскольку данные выглядят как объекты сопоставления и даже соответствуют формату JSON, нужно сделать что-то подобное, если вы не возражаете против использования поддержки Python (которая поставляется с JSON):

import json

def get_id_hw(s):
    d = json.loads(s)
    return '"id":"{}","hwVersion":"{}"'.format(d["id"], d["hwVersion"])

Мы берем строку входной строки в s и анализируем ее как JSON в словаре d. Затем мы возвращаем отформатированную строку со строками id и hwVersion в двойных кавычках, за которыми следуют столбец и значение в двойных кавычках соответствующего ключа из ранее полученного dict.

Мы можем попробовать это с помощью этого теста входные строки и печать:

# These will be our test inputs.
s1 = '{"id":"1111","name":"2222","versionCurrent":"3333","hwVersion":"4444"}'
s2 = '{"id":"5555","name":"6666","hwVersion":"7777"}'

# we pass and print them here
print(get_id_hw(s1))
print(get_id_hw(s2))

Но мы можем точно так же перебрать строки любого ввода.

Если вы действительно хотите использовать awk, вы можете, но это не Самый надежный и подходящий инструмент:

awk '{ i = gensub(/.*"id":"([0-9]+)".*/, "\\1", "g")
       h = gensub(/.*"id":"([0-9]+)".*/, "\\1", "g")
       printf("\"id\":\"%s\",\"hwVersion\":\"%s\"\n"), i, h}' /your/file

Поскольку вы упоминаете, что положение неизвестно и предполагается, что оно может быть в любом порядке, мы используем одно регулярное выражение для извлечения id, а другое для получения hwVersion, затем мы распечатываем его в заданном формате. Если значения могли бы быть чем-то иным, чем десятичные цифры, как в вашем примере, [0-9]+, но это должно было бы отражать это.

И для удовольствия, если это (это сохраняет порядок), если записи из файла, в sed:

sed -e 's#.*\("\(id\|hwVersion\)":"[0-9]\+"\).*\("\(id\|hwVersion\)":"[0-9]\+"\).*#\1,\3#' file

Он ищет две группы "id" или "hwVersion", за которыми следует :"<DECIMAL_DIGITS>".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...