Substituir segunda ocorrência entre dois pontos e colchete

0

Eu tenho que substituir cada string após dois pontos com a mesma palavra + sublinhado + número da seguinte maneira:

{"first": "1_first", "second": "1_second"}

Resultados esperados:

{"first": "first_1", "second": "second_1"}
{"first": "first_20", "second": "second_20"}
{"first": "first_33", "second": "second_33"}

Eu consegui com o primeiro:

echo '{"first": "first_1", "second": "second_1"}' | sed "s/\( \".*\",\)/ \"first_$j\",/"

O resultado é:

{"first": "first_888", "second": "second_1"}

Mas tem problemas com o segundo. Eu suponho que essa expressão é muito gananciosa:

echo '{"first": "first_1", "second": "second_1"}'|sed "s/\( \".*\)\"}/ \"second_$j\"}/"

Esse aqui é demais:

{"first": "second_888"}

Talvez haja uma maneira mais elegante de fazer isso? Com uma expressão em vez de 2?

    
por Borys 08.08.2016 / 00:16

2 respostas

1

Não tenho certeza se é isso que você deseja, substituindo os valores por strings das chaves. Funciona contanto que você não tenha (escapou) aspas dentro das chaves ou valores. Se você usa, ou melhor, usa um analisador real.

$ num=42
$ echo '{"foo": "xxx", "bar": "yyy"}' | \
  sed -E 's/"([^"]*)": "[^"]*"/"": "_'$num'"/g'
{"foo": "foo_42", "bar": "bar_42"}
    
por 08.08.2016 / 00:40
1

Usando jq :

$ cat data.json
{"first": "xxx", "second": "xxx"}
{"first": "yyy", "second": "yyy"}
{"first": "zzz", "second": "zzz"}

$ jq 'with_entries(.value = .key + "_42")' data.json
{
  "first": "first_42",
  "second": "second_42"
}
{
  "first": "first_42",
  "second": "second_42"
}
{
  "first": "first_42",
  "second": "second_42"
}

Com uma variável de shell:

$ number=9
$ jq 'with_entries(.value = .key + "_'$number'")' data.json
{
  "first": "first_9",
  "second": "second_9"
}
{
  "first": "first_9",
  "second": "second_9"
}
{
  "first": "first_9",
  "second": "second_9"
}

Se você preferir uma saída compacta:

$ jq -c 'with_entries(.value = .key + "_'$number'")' data.json
{"first":"first_9","second":"second_9"}
{"first":"first_9","second":"second_9"}
{"first":"first_9","second":"second_9"}
    
por 08.08.2016 / 09:13