Bash: Как добавить значение массива в JSON? - PullRequest
0 голосов
/ 17 октября 2019

Я собираю некоторый скрипт bash для разбора URL на его компоненты. Я заблокирован, пытаясь выяснить, как добавить значение массива к ключу в теле JSON.

Попытка:

Я проанализировал следующий URL: https://bar.foo.com/v2020/folders/8d55e749-bbd7-e811-9c19-3ca82a1e3f41/folders

Путь этого URL:

URL_PATH: v2020/folders/8d55e749-bbd7-e811-9c19-3ca82a1e3f41/folders

Массив частей пути этого URL использует

IFS='/' read -ra URL_PATH_PARTS <<< "$URL_PATH"

URL_PATH_PARTS [4]: v2020 folders 8d55e749-bbd7-e811-9c19-3ca82a1e3f41 folders

Я хочудобавьте значение массива в JSON, которое отформатировано следующим образом:

{
  ...
  "parts": ["v2020", "folders", "8d55e749-bbd7-e811-9c19-3ca82a1e3f41", "folders"]
}

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

{
  ...
  "parts": "[v2020 folders 8d55e749-bbd7-e811-9c19-3ca82a1e3f41 folders]"
}

Bash codeпарсинг URL в его компоненты:

#!/usr/bin/env bash

HREF='https://bar.foo.com/v2020/folders/8d55e749-bbd7-e811-9c19-3ca82a1e3f41/folders'
# remove quotes
HREF=$(echo $HREF | tr -d '"')
echo "  HREF: $HREF"

# extract the PROTOCOL
URL_PROTOCOL=$(echo $HREF | grep :// | sed -e's,^\(.*://\).*,\1,g')
echo "  URL_PROTOCOL: $URL_PROTOCOL"

# extract the PROTOCOL SCHEME
URL_SCHEME=`echo ${URL_PROTOCOL::-3}`
echo "  URL_SCHEME: $URL_SCHEME"

# remove the PROTOCOL -- updated
URL=$(echo $HREF | sed -e s,$URL_PROTOCOL,,g)
echo "  URL: $URL"

# extract the host and port -- updated
URL_HOSTPORT=$(echo $URL | sed -e s,$user@,,g | cut -d/ -f1)
echo "  URL_HOSTPORT: $URL_HOSTPORT"

# by request host without port
URL_HOST="$(echo $URL_HOSTPORT | sed -e 's,:.*,,g')"
echo "  URL_HOST: $URL_HOST"

# by request - try to extract the port
URL_PORT="$(echo $URL_HOSTPORT | sed -e 's,^.*:,:,g' -e 's,.*:\([0-9]*\).*,\1,g' -e 's,[^0-9],,g')"
echo "  URL_PORT: $URL_PORT"

# Extract the path
URL_PATH="$(echo $URL | grep / | cut -d/ -f2-)"
echo "  URL_PATH: $URL_PATH"

IFS='/' read -ra URL_PATH_PARTS <<< "$URL_PATH"
echo "  URL_PATH_PARTS [${#URL_PATH_PARTS[@]}]: ${URL_PATH_PARTS[@]}"

URL_COMPONENTS="{ \
    \"protocol\": \"$URL_PROTOCOL\", \
    \"scheme\": \"$URL_SCHEME\", \
    \"url\": \"$URL\", \
    \"host\": \"$URL_HOST\", \
    \"path\": \"$URL_PATH\", \
    \"parts\": \"[${URL_PATH_PARTS[@]}]\" \
}"

echo -e "\n  URL_COMPONENTS:"
echo $URL_COMPONENTS |
    jq '.'

Ответ консоли

  HREF: https://bar.foo.com/v2020/folders/8d55e749-bbd7-e811-9c19-3ca82a1e3f41/folders
  URL_PROTOCOL: https://
  URL_SCHEME: https
  URL: bar.foo.com/v2020/folders/8d55e749-bbd7-e811-9c19-3ca82a1e3f41/folders
  URL_HOST: bar.foo.com
  URL_PATH: v2020/folders/8d55e749-bbd7-e811-9c19-3ca82a1e3f41/folders
  URL_PATH_PARTS [4]: v2020 folders 8d55e749-bbd7-e811-9c19-3ca82a1e3f41 folders

  URL_COMPONENTS:
{
  "protocol": "https://",
  "scheme": "https",
  "url": "bar.foo.com/v2020/folders/8d55e749-bbd7-e811-9c19-3ca82a1e3f41/folders",
  "host": "bar.foo.com",
  "path": "v2020/folders/8d55e749-bbd7-e811-9c19-3ca82a1e3f41/folders",
  "parts": "[v2020 folders 8d55e749-bbd7-e811-9c19-3ca82a1e3f41 folders]"
}

Спасибо

Благодарю за все отзывы и предложения!

Ответы [ 3 ]

2 голосов
/ 17 октября 2019

Не связывайтесь с массивом. Используйте подстановку переменных:

URL_PATH_PARTS=${URL_PATH//\/ }         # Replace slashes with spaces
SPACES="${URL_PATH_PARTS//[^ ]} "       # Append space to avoid fence-post error.
echo "  URL_PATH_PARTS [${#SPACES}]: ${URL_PATH_PARTS}"

...

 \"parts\": [ \"${URL_PATH_PARTS// /\", \"}\" ] \  # Replace spaces with '", "'

Вы также можете покончить с промежуточной переменной 'URL_PATH_PARTS' (и потерять некоторую читабельность):

SLASHES="${URL_PATH//[^\/]}/"       # Append slash to avoid fence-post error.
echo "  URL_PATH_PARTS [${#SLASHES}]: ${URL_PATH//\// }"

...

 \"parts\": [ \"${URL_PATH//\//\", \"}\" ] \  # Replace slashes with '", "'
1 голос
/ 17 октября 2019

Текущий код, используя: \"parts\": \"[${URL_PATH_PARTS[@]}]\" для пути. Возможное решение - перебирать элементы, создавая объединенную строку с кавычками и разделителем ','

PP=
for P1 in "${URL_PATH_PARTS[@]}" ; do
  # Add ',' unless this is first item
  [ "$PP" ] && PP="$PP, "
  PP=$PP\"$P1\"
done

Заменить IN (компоненты URL)

\ "parts \": \ "[$ {URL_PATH_PARTS [@]}] \"

с

\ "частями \": [$ PP]

0 голосов
/ 18 октября 2019

Спасибо @CharlesDuffy, @ dash-o, @ AndrewVickers

Я опробовал все ваши предложения.

Предлагаемый мной подход был joelpurra / jq-hopkok

Код Bash

#!/usr/bin/env bash

URL='"https://apiuatna11.springcm.com/v201411/folders/8d55e749-bbd7-e811-9c19-3ca82a1e3f41/folders"'

# URL to components
echo $URL | ./jq-hopkok/src/url/to-components.sh

Ответ JSON

{
  "value": "https://apiuatna11.springcm.com/v201411/folders/8d55e749-bbd7-e811-9c19-3ca82a1e3f41/folders",
  "valid": true,
  "scheme": {
    "value": "https",
    "valid": true
  },
  "domain": {
    "value": "apiuatna11.springcm.com",
    "components": [
      "apiuatna11.springcm.com",
      "springcm.com",
      "com"
    ],
    "tld": "com",
    "valid": true
  },
  "port": {
    "value": null,
    "separator": false,
    "valid": true
  },
  "path": {
    "value": "/v201411/folders/8d55e749-bbd7-e811-9c19-3ca82a1e3f41/folders",
    "components": [
      "v201411",
      "folders",
      "8d55e749-bbd7-e811-9c19-3ca82a1e3f41",
      "folders"
    ],
    "valid": true
  },
  "query": {
    "value": null,
    "separator": false,
    "components": [],
    "valid": true
  },
  "fragment": {
    "value": null,
    "separator": false,
    "valid": true
  }
}
...