Заменить второе появление между двоеточием и скобкой

Я должен заменить каждую строку после двоеточия на то же слово + знак подчеркивания + следующим образом:

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

Ожидаемые результаты:

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

Я преуспел в первом:

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

Результат:

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

Но есть проблемы со вторым. Я полагаю, что это выражение слишком жадно:

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

Это слишком много:

 {"first": "second_888"} 

Может быть, есть еще более элегантный способ сделать это? С одним выражением вместо 2?

Я не уверен, что это то, что вы хотите, заменив значения на строки из ключей. Работает до тех пор, пока у вас нет (экранированных) кавычек в ключах или значениях. Если вы это сделаете или даже можете, лучше используйте настоящий парсер.

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

Используя 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" } 

С переменной оболочки:

 $ 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" } 

Если вы предпочитаете компактный выход:

 $ 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"}