Reputation: 188
I have yml file in below format.
Backendapp:
Name: spring-rest
Image: "testuser/backend"
ImageTag: "latest"
ImagePullPolicy: "Always"
Port: 8080
replicaCount: 2
Frontendapp:
Name: spring-js
Image: "testuser/frontend"
ImageTag: "latest"
ImagePullPolicy: "Always"
replicaCount: 2
How to replace 'Image', 'ImageTag' for Backendapp through Bash?
Edit: say file name is test.yml with above contents. Then, I would like to replace 'Image' and 'ImageTag' with some another value(say 'teststring','latest2' resp.) for 'Backendapp' part.
Modified file should look like below.
Backendapp:
Name: spring-rest
Image: "teststring"
ImageTag: "latest2"
ImagePullPolicy: "Always"
Port: 8080
replicaCount: 2
Frontendapp:
Name: spring-js
Image: "testuser/frontend"
ImageTag: "latest"
ImagePullPolicy: "Always"
replicaCount: 2
Upvotes: 1
Views: 3929
Reputation: 133428
Following awk
may help you on same:
awk '
/:$/{
flag=""
}
/Backendapp/||/Frontendapp/{
flag=1
}
flag && NF && (/Image:/||/ImageTag:/){
match($0,/^[[:space:]]+/);
val=substr($0,RSTART,RLENGTH);
$NF="teststring";
print val $0;
next
}
1
' Input_file
Output will be as follows:
Backendapp:
Name: spring-rest
Image: teststring
ImageTag: teststring
ImagePullPolicy: "Always"
Port: 8080
replicaCount: 2
Frontendapp:
Name: spring-js
Image: teststring
ImageTag: teststring
ImagePullPolicy: "Always"
replicaCount: 2
Solution 2nd: As per OP, OP needs to have shell variable into awk
variable too then following may help on same:
awk -v val_shell="$shell_variable" '
/:$/{
flag=""
}
/Backendapp/||/Frontendapp/{
flag=1
}
flag && NF && (/Image:/||/ImageTag:/){
match($0,/^[[:space:]]+/);
val=substr($0,RSTART,RLENGTH);
$NF=val_shell;
print val $0;
next
}
1
' Input_file
Upvotes: 2
Reputation: 31
Here's your solution. It basically uses SED to do the replacement. Just copy and paste the bits between "START OF SCRIPT" and "END OF SCRIPT" into any bash script then run (simple instructions below):
#!/bin/bash
# SED script will be stored here ...
sedscript=/tmp/sedscript.sed
# first argument to script is the parent name ...
parent="${1}"
# second argument to the script is child name...
child="${2}"
# third argument is the value to replace the CHILD value with ...
value="$3"
cat << EOF > "${sedscript}"
# find parent ...
/^${parent}:.*$/{
p
# load next line into input ...
n
# another parent found to print it ...
/^[a-z|A-Z|0-9]\{1\}:.*$/{
# we have found another parent
# so stop processing ...
b print_default_text
}
:search_for_child
/^[ | ]*$child[ | ]*:.*$/{
s/^\([^:]*:[ |\"| ]*\)[^\"]*\(.*\)$/\1$value\2/p
b dont_print_default_text
}
p
n
b search_for_child
}
:print_default_text
p
:dont_print_default_text
EOF
sed -n -f "${sedscript}" "input.yml"
Now we save the script as alter.sh (for example) then run it like this (changing the Frontendapp/Image to "another-image-name"):
./alter.sh Frontendapp Image "another-image-name"
Backendapp: Name: spring-rest Image: "teststring" ImageTag: "latest2" ImagePullPolicy: "Always" Port: 8080 replicaCount: 2
Frontendapp: Name: spring-js Image: "testuser/frontend" ImageTag: "latest" ImagePullPolicy: "Always" replicaCount: 2
Backendapp: Name: spring-rest Image: "teststring" ImageTag: "latest2" ImagePullPolicy: "Always" Port: 8080 replicaCount: 2
Frontendapp: Name: spring-js Image: "another-image-name" ImageTag: "latest" ImagePullPolicy: "Always" replicaCount: 2
Note: the script takes care of quotes too, i.e. if the original value has quotes then the new value will be surrounded in quotes also.
Hope this helps ....
Upvotes: 2
Reputation: 92854
Awk
solution:
awk 'NF==1 && /^[^[:space:]]+:/{ f=(/^(Back|Front)endapp:/) }
f && $1 ~ /^Image(Tag)?:/{ $1=" teststring" }1' test.yml
The output:
Backendapp:
Name: spring-rest
teststring: "testuser/backend"
teststring: "latest"
ImagePullPolicy: "Always"
Port: 8080
replicaCount: 2
Frontendapp:
Name: spring-js
teststring: "testuser/frontend"
teststring: "latest"
ImagePullPolicy: "Always"
replicaCount: 2
Upvotes: 1