To store things, sed has a hold space and h/H commands to copy/append the pattern space to the host space (hold), g/G to get what's held and replace/append to the pattern space (and x to exchange hold and pattern space).
sed -E ' /^ {4}rtr-/h /snmp_location/{ s/$/\ \ routers:\ hosts:/ G }' sed -E ' /^ {4}rtr-/h /snmp_location/ { s/$/\ \ routers:\ hosts:/ G }' In a less antiquated language, thatthe equivalent would look like:
perl -pe ' $hold = $_ if /^ {4}rtr-/; $_ .= "\nrouters:\n hosts:\n$hold" if /snmp_location/' perl -pe ' $hold = $_ if /^ {4}rtr-/; $_ .= "\nrouters:\n hosts:\n$hold" if /snmp_location/' Or to avoid adding that routers section if rtr- was not found:
perl -pe ' $hold = $_ if /^ {4}rtr-/; $_ .= "\nrouters:\n hosts:\n$hold" if /snmp_location/ && defined $hold' In sed:
sed -E ' /^ {4}rtr-/h /snmp_location/ { G s/(\n)(.)/\1\1routers:\1 hosts:&/; t s/\n// }' Where we first append the hold space to the pattern space for lines that contain snmp_location, and only insert the routers section before what was appended if non-empty (matches .). Also note the then command that branches to the end if the substitution succeeded.
Note that if there are several occurrences of rtr- before the snmp_location line, all those will consider the last, not first. In perl you can change $host = to $host //= to skip the assignment if $hold is already defined. In sed, you could change it to:
sed -E ' /^ {4}rtr-/ { x /./ { # already found x b after_g } g : after_g } /snmp_location/ { G s/(\n)(.)/\1\1routers:\1 hosts:&/; t s/\n// }' Or, assuming the first occurrence of rtr- won't be on the first line (with GNU sed, you could replace 1 with 0 to cover for that case):
sed -E ' 1, /^ {4}rtr-/ { /^ {4}rtr-/ h } /snmp_location/ { G s/(\n)(.)/\1\1routers:\1 hosts:&/; t s/\n// }'