JQ вычитает 13 из моего целого числа, когда оно добавляет его во второе местоположение, но не в первое - PullRequest
0 голосов
/ 24 мая 2018

У меня есть скрипт, который использует Docker env vars для настройки файла json при запуске.Функция использует одну и ту же переменную ENV дважды в одной и той же команде JQ, и в первом месте целое число остается неизменным, а во второй строке JQ вычитает 13 (WTF?) Из числа.Кто-нибудь может объяснить это?И что более важно, как я могу предотвратить это.

Примечание: Чтобы конфигурация была действительной, второй экземпляр должен быть целым без кавычек.Тестирование показывает, что цитирование целого числа приводит к ожидаемому выводу, но неверной конфигурации.

Env Var

DISCORD_CHANNEL=448887356515418113

Функция Bash:

function updateDiscordConfig {
  echo "Setting Discord configuration..."
  jq ".discord |= . + {\"token\":\"${DISCORD_TOKEN}\"} | .discord.channels.channels |= . + {\"${DISCORD_CHANNEL}\": {}} | .minecraft.dimensions.generic |= . + {\"discordChannel\": [${DISCORD_CHANNEL}]}" ${DISCORD_SRCCONFIG} | sponge ${DISCORD_DESTCONFIG}
}

Выход:

// First output
"channels": {
  "448887356515418113": {}
}

// Second output
"discordChannel": [
    448887356515418100
],

Обновление : я заменил второе обновление экземпляра на строку с использованием sed:

function updateDiscordConfig {
  echo "Setting Discord configuration..."
  jq ".discord |= . + {\"token\":\"${DISCORD_TOKEN}\"} | .discord.channels.channels |= . + {\"${DISCORD_CHANNEL}\": {}}" ${DISCORD_SRCCONFIG} | sponge ${DISCORD_DESTCONFIG}
  sed -i "/discordChannel/c\   \"discordChannel\" : [${DISCORD_CHANNEL}]," ${DISCORD_DESTCONFIG}
}

Ответы [ 2 ]

0 голосов
/ 24 мая 2018

Как правило, по этой причине не следует использовать числовой тип для больших числовых строк в JSON.Но если Discord требует целое число - и если он может получить правильное необоснованное значение из конфигурации с тем, что это использует для его анализа - тогда вам нужен другой подход.Возможно Python?

function updateDiscordConfig {
  echo "Setting Discord configuration..."
  python -c "import json, sys; conf = json.load(sys.stdin); conf['discord']['token']='$DISCORD_TOKEN'; conf['discord']['channels']['channels']='$DISCORD_CHANNEL';conf['minecraft']['dimensions']['generic']['discordChannel']=[$DISCORD_CHANNEL];print(json.dumps(conf));" ${DISCORD_SRCCONFIG} | sponge ${DISCORD_DESTCONFIG}
}
0 голосов
/ 24 мая 2018

К сожалению, вы столкнулись с одним из основных ограничений jq - числовой точностью.jq сопоставляет числа JSON с 64-разрядными числами IEEE 754.Это обсуждается в jq FAQ в разделе «Предостережения».

Обходные пути

Если вы не хотите работать с другим языком программирования, вы можете использовать «BigInt»."module for jq - https://gist.github.com/pkoppstein/d06a123f30c033195841

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

Если вам просто нужно сложение, вы можетеиспользуйте это jq def:

# The args should be strings representing non-negative integers
# without a leading "+":
def add(num1;num2):
  if (num1|length) < (num2|length) then add(num2;num1)
  else  (num1 | explode | map(.-48) | reverse) as $a1
      | (num2 | explode | map(.-48) | reverse) as $a2
      | reduce range(0; num1|length) as $ix
          ($a2;  # result
           ( $a1[$ix] + .[$ix] ) as $r
           | if $r > 9 # carrying
             then
               .[$ix + 1] = ($r / 10 | floor) + 
                            (if $ix + 1 >= length then 0 else .[$ix + 1] end )
               | .[$ix] = $r - ( $r / 10 | floor ) * 10
             else
               .[$ix] = $r
             end )
      | reverse | map(.+48) | implode
  end ;

Использование

Один из способов использовать это - скопировать его в файл (скажем, add.jq) в вашей библиотеке jq (например, ~ / .jq/) и используйте include, чтобы включить его, например, как показано ниже:

jq -n  'include "add"; 
        add("448887356515418113";"448887356515418113")'
"897774713030836226"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...