#linux #bash #sed
#linux #bash #sed
Вопрос:
Я пытаюсь использовать sed для преобразования этого json:
{
"terraform_version": "0.14.8",
"terraform_revision": "",
"provider_selections": {
"registry.terraform.io/hashicorp/azuread": "1.3.0",
"registry.terraform.io/hashicorp/azurerm": "2.47.0",
"registry.terraform.io/hashicorp/cloudinit": "2.1.0",
"registry.terraform.io/hashicorp/external": "2.0.0",
"registry.terraform.io/hashicorp/kubernetes": "2.0.2",
"registry.terraform.io/hashicorp/local": "2.0.0",
"registry.terraform.io/hashicorp/null": "3.0.0",
"registry.terraform.io/hashicorp/template": "2.2.0",
"registry.terraform.io/hashicorp/tls": "3.0.0"
},
"terraform_outdated": false
}
чтобы выглядеть так:
{
"terraform_version": "0.14.8",
"terraform_revision": "",
"provider_selections": "{"registry.terraform.io/hashicorp/azuread":"1.3.0","registry.terraform.io/hashicorp/azurerm":"2.47.0","registry.terraform.io/hashicorp/cloudinit":"2.1.0","registry.terraform.io/hashicorp/external":"2.0.0","registry.terraform.io/hashicorp/kubernetes":"2.0.2","registry.terraform.io/hashicorp/local":"2.0.0","registry.terraform.io/hashicorp/null":"3.0.0","registry.terraform.io/hashicorp/template":"2.2.0","registry.terraform.io/hashicorp/tls":"3.0.0"}",
"terraform_outdated": "false"
}
По сути, provider_selections должен быть заключен в кавычки, а кавычки внутри него экранированы. Мне также нужно, чтобы значение terraform_outdated было строкой.
Я попытался это:
cat jsondata.json | sed 's/{/"{/2' | sed 's/}/"}/1'
но я не могу понять остальное.
Комментарии:
1. Используйте инструмент, предназначенный для этой работы, например
jq
.2.
jq
не работает с бегунами github, поэтому я пытаюсь найти обходной путь. Я сообщил о проблеме: github.com/stedolan/jq/issues/22873. Чтение вашего билета, связанного выше: это не ошибка jq; Это происходит от чего-то другого. (Это трассировка стека JavaScript, но jq написан не на JavaScript).
4. Что касается этого билета:
terraform version -json | tee >(cat >amp;2) | (jq . || cat >/dev/null)
кстати, это может дать нам больше возможностей для дальнейшего выяснения, в чем дело. Но в целом, я был бы намного счастливее, пытаясь отладить «почему jq не работает в моей среде github runner?» чем «как я могу редактировать JSON с помощью sed?». Последнее — это то, чего просто не следует делать.
Ответ №1:
Если вы можете использовать python :
#!/usr/bin/env bash
python -c "import json,sys
data=json.loads(open(sys.argv[1]).read())
data['provider_selections'] = json.dumps(data['provider_selections'])
print(json.dumps(data))
" data.json
Ответ №2:
Используя sed, это выглядит следующим образом:
sed -r '/: {/{x;N;:L;N;s/},/},/;TL;s/"/\"/g;x;G;s/n *//g};s/: ([^"].*[^,])(,)?$/: "1"2/' file.json
Расширено до нескольких строк
sed -r '
/: {/{
x
N
:L
N
s/},/},/
TL
s/"/\"/g
x
G
s/n *//g
}
s/: ([^"].*[^,])(,)?$/: "1"2/
' file.json
Однако использование sed для преобразования формата, подобного описанному выше, не является универсальным…
Ответ №3:
Если ed
это приемлемо / доступно.
#!/usr/bin/env bash
ed -s file.json <<-'EOF'
g/: {/ 1;/},/-1s/"/\"/g
g/: {/ 1;/},/-1s/[[:blank:]]*//
g/: {/ 1;/},/s/[[:blank:]]{1,}//
g/: {/;/},/j
., s/(.*) ({?.*}?)/1 "2"/
,p
Q
EOF
Если вывод правильный, просто измените Q
w
, чтобы отредактировать файл на месте.
Тестировалось только на GNU ed
.