{
"id": "a1234567-89ab-cdef-0123-456789abcdef",
"properties": {
...
"my_id": "c1234567-89ab-cdef-0123-456789abcdef",
...
}
Given the above in a file, I want to be able to perform a match (including the 4 leading spaces) on my_id
and then append a new line "my_value": "abcd",
. The desired output would look like this:
{
"id": "a1234567-89ab-cdef-0123-456789abcdef",
"properties": {
...
"my_id": "c1234567-89ab-cdef-0123-456789abcdef",
"my_value": "abcd",
...
}
Using examples online, I'm unable to get the command to work. Here is an example of something I have tried: sed '/.*"my_id".*/a "my_value": "abcd",' test.json
, for which I receive the following error: command a expects \ followed by text
.
What is the correct way to structure this command?
CodePudding user response:
Using any awk:
$ awk -v new='"my_value": "abcd",' '{print} sub(/"my_id":.*/,""){print $0 new}' file
{
"id": "a1234567-89ab-cdef-0123-456789abcdef",
"properties": {
...
"my_id": "c1234567-89ab-cdef-0123-456789abcdef",
"my_value": "abcd",
...
}
I'm using this:
sub(/"my_id":.*/,""){print $0 new}
instead of the briefer:
sub(/"my_id":.*/,new)
so it won't break if the new string contains any backreference chars such as &
.
CodePudding user response:
awk
procedure with passed argument for insert value
The following awk
procedure allows for 'abcd'
to be passed as an argument for insertion (allowing it to be set in a bash script if required).
awk -v insertVal="abcd" '/"my_id":/{$0=$0"\n \"my_value\": \""insertVal"\","} {print}' dat.txt
explanation
The required insertion string ('abcd'
in this case) is passed as an argument using the -v
variable switch followed by a variable name and value: insertVal="abcd"
.
The first awk
action
block has a pattern
condition to only act on lines containing the target-line string (in this case "my_id":
). When a line with that pattern
is found, the line is extended with a new line mark \n
, the required four spaces to start the next line, the specified key
named "my_value"
, and the value associated with the key, passed by argument as the variable named insertVal
("abcd"
), and the final ,
character. Note the need to escape the "
quotes to render them.
The final awk
block, prints the current line (whether or not it was modified).
test
The procedure was tested on Mac Terminal using GNU Awk 5.2.0.
The output generated (from the input data saved to a file named dat.txt
) is:
{
"id": "a1234567-89ab-cdef-0123-456789abcdef",
"properties": {
...
"my_id": "c1234567-89ab-cdef-0123-456789abcdef",
"my_value": "abcd",
...
}
CodePudding user response:
Using sed
$ sed -e '/my_id/{p;s/id.*"/value": "abcd"/' -e '}' input_file
{
"id": "a1234567-89ab-cdef-0123-456789abcdef",
"properties": {
...
"my_id": "c1234567-89ab-cdef-0123-456789abcdef",
"my_value": "abcd",
...
}
CodePudding user response:
With GNU awk
and with your shown samples and attempts please try following awk
code.
awk -v newVal='"my_value": "abcd",' -v RS= 'match($0,/(.*)("my_id": "[^"]*",)(.*)/,arr){print arr[1] arr[2] newVal arr[3]}' Input_file