Как получить json-данные, используемые в каждом выражении curl, при использовании xargs и сопоставить их соответствующему результату?

Вопрос или проблема

У меня есть текстовый файл, содержащий аргументы команды curl. Вот как выглядит файл

'https://example.com/tl/' -X POST -H 'Content-Type: application/json' --data-raw '{"email":"username2",}'
'https://example.com/tl/' -X POST -H 'Content-Type: application/json' --data-raw '{"email":"username3",}'
'https://example.com/tl/' -X POST -H 'Content-Type: application/json' --data-raw '{"email":"username4",}'
'https://example.com/tl/' -X POST -H 'Content-Type: application/json' --data-raw '{"email":"username5",}'
'https://example.com/tl/' -X POST -H 'Content-Type: application/json' --data-raw '{"email":"username6",}'

Это команда, которую я использую

cat /AbsolutePath/Inputfile.txt | xargs -P 10000 -n 10 curl -s | jq '.message'

Я использую jq, чтобы парсить json в командной строке

Что я хочу, так это

  1. Провести или отправить вывод вышеуказанной команды в другую команду, чтобы, если message содержит определенный текст, получить значение email, использованное в соответствующей команде curl, и записать это в лог файл или создать файл с именем usernameX.txt

Например, только если сообщения cURL команды для username2 и username5 равны “success”, эти два имени пользователя должны быть записаны в лог файл или должны быть созданы два файла username2.txt и username5.txt.

Чтобы удовлетворить вашему требованию, каждое “message” вывода должно быть связано с соответствующим введенным “mail”.

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

#! /bin/bash
# печать   
jq .mail -rj "${@: -1]}"      # печать mail без новой строки
echo -n " "                  
curl -s "$@" | jq .message -r

Затем передайте результат в awk '$2=="success"{print $1}'

Кроме того, вы можете попробовать это

cat /AbsolutePath/Inputfile.txt |
    xargs -P 10000 -n 10 curl -s |
    jq -s 'to_entries|.[]|select(.value.message=="success")|.key+1' |
    awk 'FILENAME=="-"{line[$0]=1}  FILENAME != "-" && line[FNR]==1{print gensub(/.*--data-raw /, "", "g", $0)}' - /AbsolutePath/Inputfile.txt | 
    jq .mail -r

По сути, jq получает индексы успешных сообщений, а awk читает индексы и извлекает последнюю часть соответствующей n-й строки из файла.

Рекомендуется использовать простой awk скрипт.

скрипт awk

awk '{system("curl "$0)}' /AbsolutePath/Inputfile.txt | jq

скрипт awk с фильтрацией успешного сообщения

awk '{system("curl "$0)}' /AbsolutePath/Inputfile.txt | grep "success"

TLDR

cat input.txt |
  xargs -P0 -L1 sh -c 'curl -s "$@" | jq -c --arg username $(echo "${@: -1}" | jq -r .email) "{\$username, message}"' sh |
  jq -r 'select(.message == "success") | .username'

Как

Вы запросили печать имени пользователя в зависимости от соответствующего тела ответа, но ваш входной файл состоит из аргументов curl, и вы не упомянули, содержит ли тело ответа имя пользователя.

Поэтому я решил сначала разобрать ваш последний аргумент, чтобы получить имя пользователя, например:

cat input.txt |
  xargs -P0 -L1 sh -c 'curl -s "$@" | jq -c --arg username $(echo "${@: -1}" | jq -r .email) "{\$username, message}"' sh
{"username":"username2","message":"failure"}
{"username":"username4","message":"failure"}
{"username":"username3","message":"success"}
{"username":"username5","message":"failure"}
{"username":"username6","message":"success"}

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

jq -r 'select(.message == "success") | .username'
cat input.txt |
  xargs -P0 -L1 sh -c 'curl -s "$@" | jq -c --arg username $(echo "${@: -1}" | jq -r .email) "{\$username, message}"' sh |
  jq -r 'select(.message == "success") | .username'
username3
username6

Для справки, вот Ruby HTTP сервер, который я использовал для отладки.

rackup -rjson -b 'run ->(_) { [200, {}, [JSON.dump(message: rand(2) == 0 ? "success" : "failure")]] }'

Ответ или решение

Как получить данные JSON, используемые в каждой команде curl с помощью xargs и сопоставить их с соответствующим результатом

В данной ситуации вам необходимо обрабатывать файл, содержащий команды curl, которые отправляют данные JSON, и сопоставлять результаты запросов с электронными адресами, содержащимися в этих командах. Мы рассмотрим подход, который поможет вам достичь этой цели. Для этого будет использован набор утилит командной строки: xargs, curl и jq.

Шаг 1: Подготовка файла с командами curl

Файл, который вы используете, содержит команды curl с помощью синтаксиса, аналогичного следующему:

'https://example.com/tl/' -X POST -H 'Content-Type: application/json' --data-raw '{"email":"username2",}'
'https://example.com/tl/' -X POST -H 'Content-Type: application/json' --data-raw '{"email":"username3",}'
...

Шаг 2: Создание оболочечного скрипта для обработки вхождений

Для того чтобы сопоставить результаты запросов с соответствующими email-адресами, вы можете написать небольшой оболочечный скрипт. Этот скрипт будет извлекать адрес электронной почты из команды и получать ответ от curl, затем выводить результаты в формате JSON.

#!/bin/bash
# Обработка каждого запроса curl и извлечение email
email=$(echo "${@: -1}" | jq -r .email)
response=$(curl -s "$@")
echo "{\"username\":\"$email\", \"message\":$(echo "$response" | jq .message)}"

Сохраните этот код в файл, например curl_processor.sh, сделайте его исполняемым:

chmod +x curl_processor.sh

Шаг 3: Запуск команды с xargs

Теперь можно использовать xargs для обработки вашего входного файла и выполнения команд curl:

cat /AbsolutePath/Inputfile.txt |
xargs -P 10000 -L 1 ./curl_processor.sh |
jq -r 'select(.message == "success") | .username'

Эта команда:

  1. Читает содержимое входного файла с командами curl.
  2. Использует xargs, чтобы запустить каждую команду в своем собственном процессе.
  3. Параллельно выполняет команды до 10000 процессов (можно скорректировать в зависимости от нагрузки вашего сервера).
  4. Обрабатывает вывод каждой команды через jq, фильтруя успехи и извлекая имена пользователей.

Шаг 4: Сохранение результатов в файлы или журналы

Если необходимо сохранить результаты в файл, вы можете перенаправить вывод в файл:

cat /AbsolutePath/Inputfile.txt |
xargs -P 10000 -L 1 ./curl_processor.sh |
jq -r 'select(.message == "success") | .username' > successful_usernames.txt

Также вы можете создавать отдельные файлы для каждого успешного пользователя:

cat /AbsolutePath/Inputfile.txt |
xargs -P 10000 -L 1 ./curl_processor.sh |
jq -r 'select(.message == "success") | .username' |
while read username; do
    touch "${username}.txt"    # Создает файл с именем пользователя
done

Заключение

Данный подход позволяет эффективно обрабатывать команды curl, извлекать связанные с ними адреса электронной почты и записывать успехи, используя простые инструменты командной строки. Это обеспечивает гибкость и возможность масштабирования процесса обработки запросов и результатов.

Оцените материал
Добавить комментарий

Капча загружается...