- Вопрос или проблема
- скрипт awk
- скрипт awk с фильтрацией успешного сообщения
- TLDR
- Как
- Ответ или решение
- Как получить данные JSON, используемые в каждой команде curl с помощью xargs и сопоставить их с соответствующим результатом
- Шаг 1: Подготовка файла с командами curl
- Шаг 2: Создание оболочечного скрипта для обработки вхождений
- Шаг 3: Запуск команды с xargs
- Шаг 4: Сохранение результатов в файлы или журналы
- Заключение
Вопрос или проблема
У меня есть текстовый файл, содержащий аргументы команды 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 в командной строке
Что я хочу, так это
- Провести или отправить вывод вышеуказанной команды в другую команду, чтобы, если
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'
Эта команда:
- Читает содержимое входного файла с командами curl.
- Использует
xargs
, чтобы запустить каждую команду в своем собственном процессе. - Параллельно выполняет команды до 10000 процессов (можно скорректировать в зависимости от нагрузки вашего сервера).
- Обрабатывает вывод каждой команды через
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
, извлекать связанные с ними адреса электронной почты и записывать успехи, используя простые инструменты командной строки. Это обеспечивает гибкость и возможность масштабирования процесса обработки запросов и результатов.