Извлеките значение из вывода команды и используйте значение в качестве параметра для следующей команды

Привет, я пытаюсь

curl -v --request POST https://example.com --data-urlencode "username=usr]” --data-urlencode "password=[pass]” 

передайте вывод в поле [TOKEN] здесь:

 curl -D - --request POST https://example.com --data-urlencode token=[TOKEN] 

Однако я не знаком с JSON, так как мой вывод для первой команды

 { "token": "value_of_token" } 

Как я могу взять "value_of_token" и заставить его быть [TOKEN] ?

2 Solutions collect form web for “Извлеките значение из вывода команды и используйте значение в качестве параметра для следующей команды”

Чтобы наиболее эффективно взять значение value_of_token из вывода команды curl , value_of_token вывод в команду sed (stream editor). Используйте команду подстановки $() чтобы сохранить результат в переменной оболочки:

 token=$(curl ... | sed -n '/ *"token": *"/ { s///; s/".*//; p; }') 

Затем вы можете ссылаться на token переменной как параметр на вторую команду curl :

 curl ... token="$token" 

Объяснение команды sed :

 sed -n '/ *"token" *: *"/ { s///; s/".*//; p; q; }' 
  • -n указывает sed не печатать каждую строку ввода

  • / *"token" *: *"/ адресует строку, содержащую значение. Этот шаблон (регулярное выражение) соответствует всему началу строки, вплоть до первой двойной кавычки, ограничивающей значение токена.

  • { запустите командный блок, который будет применен к адресной строке.

  • s///; команда sed для удаления того, что было ранее согласовано (в адресной части). Строка (« value_of_token" пространство») теперь выглядит так: value_of_token"

  • s/".*// sed, чтобы удалить оставшуюся двойную кавычку ( " ) и все после.

  • p sed для печати текущей (отредактированной) строки («пространство шаблонов» в терминологии sed ).

  • q Немедленно выйдите из сценария sed, не обрабатывая больше ввода

  • '}' завершает командный блок.

Например,

 $ echo ' { "token": "value_of_token" } ' | sed -n '/ *"token" *: *"/ { s///; s/".*//; p; }' value_of_token $ 

Этот метод намного эффективнее, чем объединение других команд для достижения одного и того же результата. Эта команда sed предполагает, что на входе JSON нет символов табуляции. Если существуют табуляции, команда sed потребует изменения.

Во-первых, обратите внимание, что мне пришлось заменить URL-адрес, который у вас есть в ваших командах, с помощью <URL> потому что stackexchange думал, что я спам, и не позволял мне публиковать сообщения.

Хорошо, у вас есть два вопроса:

1) Как вы делаете вывод одной команды и делаете ее аргументом другой команды?

Ответ: самым каноническим методом было бы использовать подстановку команд оболочки, заменив ваш аргумент во второй команде на $( <first command> ) следующим образом:

 curl -D - --request POST <URL> --data-urlencode token=$( curl -v --request POST <URL> --data-urlencode "username=usr]” --data-urlencode "password=[pass]” ) 

Однако для удобства чтения вы действительно должны делать это в отдельных строках, сохраняя вывод из первой команды и повторно используя ее так:

 token=$( curl -v --request POST <URL> --data-urlencode "username=usr]” --data-urlencode "password=[pass]” ) curl -D - --request POST <URL> --data-urlencode token="$token" 

Кроме того, для полноты и потому, что вы специально спросили, как «труба», вы можете использовать команду xargs вместо замены команды оболочки:

 curl -v --request POST <URL> --data-urlencode "username=usr]” --data-urlencode "password=[pass]” | xargs "curl -D - --request POST <URL> --data-urlencode token="{} 

Однако, как вы отметили, ваш вывод из первой команды не совсем то, что вы ищете как ваш токен; таким образом, вышеупомянутые решения не будут работать так, как вы ожидаете, что подводит нас к следующему вопросу:

2) Как мы можем изолировать только «value_of_token» от всего выхода JSON?

Не попадая в какой-либо JSON API, простая конвейерная обработка grep, head и cut должна выполнять эту работу:

 token=$( curl -v --request POST <URL> --data-urlencode "username=usr]” --data-urlencode "password=[pass]” ) | grep '"token":' | head -1 | cut -d ':' -f 2 | cut -d '"' -f 2 curl -D - --request POST <URL> --data-urlencode token="$token" 

Обратите внимание, что head -1 на всякий случай, если на выходе выводятся несколько строк токена, и в этом случае используется только первый.

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

  • Как конвертировать JSON-файл в другой формат
  • Где я могу найти сценарий оболочки для разбора JSON на busybox?
  • awk-скрипт для удаления блоков в json
  • Подстановка переменных Bash в строке JSON
  • Загрузите документы, на которые ссылается веб-страница с wget
  • проанализировать журналы Mongodb с syslog-ng
  • Повторение текста и выполнение команды с помощью jq
  • Как подсчитать количество вхождений слова в текстовый файл с помощью командной строки?
  • отправить json через rsyslog в elasticsearch
  • Как преобразовать вывод ps (1) в JSON?
  • возможна одиночная команда jq с несколькими выходами?
  • Linux и Unix - лучшая ОС в мире.