Input file
Ranges:
- PeakK2:8.8.9
- rover-heal:3.3.1
Arg: V1
change: 1
Firstly, check if the string cpu-management exists in the file, if not add it after the rover-heal line like below.
Ranges:
- PeakK2:8.8.9
- rover-heal:3.3.1
- cpu-management:1.9.0
Arg: V1
change: 1
I came up with a one liner
grep -e "cpu-management:" test.yaml || sed -i -e "/rover-heal/- cpu-management:${version}/" test.yaml
where version
is the environmental variable.
Error:
sed: -e expression #1, char 16: unknown command: `-'
This could be done with awk
, please try following. You can use it as a single code.
awk -v val="${version}" '
FNR==NR{
if($0~/cpu-management/){
found=1
}
next
}
/rover/ && found==""{
print $0 ORS "- cpu-management:" val
next
}
1
' Input_file Input_file
OR as per Ed sir's suggestion you could do following too use either above OR use following.
awk -v val="${version}" '
FNR==NR{
if($0~/cpu-management/){
found=1
}
next
}
{
print
}
/rover/ && !found{
print "- cpu-management:" val
}
' Input_file Input_file
For your shown samples output will be as follows:
Ranges:
- PeakK2:8.8.9
- rover-heal:3.3.1
- cpu-management:1.9.0
Arg: V1
change: 1
Explanation: Adding detailed explanation for above.
awk -v val="${version}" ##Starting awk program from here.
FNR==NR{ ##Checking condition FNR==NR which will be treu when 1st time Input_file is being read.
if($0~/cpu-management/){ ##Checking condition if line contains cpu-management then do following.
found=1 ##Setting found to 1 here.
}
next ##next will skip all further statements from here.
}
/rover/ && found==""{ ##Checking if line has rover AND found is NULL then do following.
print $0 ORS "- cpu-management:" val ##Printing current line ORS with new value.
next ##next will skip all further statements from here.
}
1 ##Printing current line here.
' Input_file Input_file ##Mentioning Input_file name here.
Ignoring the detail about cpu-management already existing in the file (that doesn't seem to be a fundamental aspect of the question, and the provided solution already works for that), the classic sed
solution for the replacement is to use a
:
$ sed "/^- rover-heal/a\\
- cpu-management:${version}
" input-file
Ranges:
- PeakK2:8.8.9
- rover-heal:3.3.1
- cpu-management:
Arg: V1
change: 1
If you're using bash, you can simplify the input with:
$ sed $'/^- rover-heal/a\\\n'"- cpu-management:$version"$'\n' input-file
Ranges:
- PeakK2:8.8.9
- rover-heal:3.3.1
- cpu-management:
Arg: V1
change: 1
Note that some sed allow you to skip the embedded new-line, but not all do.
Assuming cpu-management
should be checked only after rover-heal
line:
$ version='1.9.0'
$ sed -E '/rover-heal/{$!N; /cpu-management/! s/\n|$/\n- cpu-management:'"${version}"'&/}' ip.txt
Ranges:
- PeakK2:8.8.9
- rover-heal:3.3.1
- cpu-management:1.9.0
Arg: V1
change: 1
This was tested on GNU sed
, syntax might vary for other implementations.
/rover-heal/
line to be matched
$!N
get another line, unless rover-heal
is found on the last line of the input file/cpu-management/!
check if cpu-management
is not present
\n|$
match newline or end of line and add details as neededUse -i
option for inplace editing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With