1

I have a list of servers and services running on them and would wish to append the servername as a prefix to the following services

Consider the following input

"SERVER": "us-east-1e-421"
"SERVICES.SNMP.STATUS": "ok"
"SERVICES.NTP.LATENCY": "1.644"
"SERVICES.POSTFIX.STATUS": "ok"
"SERVER": "us-west-1c-353"
"SERVICES.SNMP.STATUS": "ok"
"SERVICES.NTP.STATUS": "ok"
"SERVICES.NTP.LATENCY": "1.541"
"SERVICES.RSYNC.STATUS": "ok"
"SERVICES.NGINX.STATUS": "ok"

So what i want is like

us-east-1e-421 SERVICES.SNMP.STATUS ok
us-east-1e-421 SERVICES.NTP.LATENCY 1.644
us-east-1e-421 SERVICES.POSTFIX.STATUS ok
us-west-1c-353 SERVICES.SNMP.STATUS ok
us-west-1c-353 SERVICES.NTP.STATUS ok
us-west-1c-353 SERVICES.NTP.LATENCY 1.541
us-west-1c-353 SERVICES.RSYNC.STATUS ok
us-west-1c-353 SERVICES.NGINX.STATUS ok

I'm ok with basic sed for single line or basic search/replace and i tried reading thru some of the sed guides posted before eg https://docstore.mik.ua/orelly/unix/sedawk/appa_03.htm but this is overboard for my knowledge and would need some help

sed '/([a-z]-[a-z]-[a-z0-9]-[0-9])/ N; s/\n"/\1 /g'

3 Answers 3

3

Alternative awk solution:

awk -F': ' '{ gsub(/"/,"") }/SERVER/{ s=$2; next }{ print s, $1, $2 }' file

The output:

us-east-1e-421 SERVICES.SNMP.STATUS ok
us-east-1e-421 SERVICES.NTP.LATENCY 1.644
us-east-1e-421 SERVICES.POSTFIX.STATUS ok
us-west-1c-353 SERVICES.SNMP.STATUS ok
us-west-1c-353 SERVICES.NTP.STATUS ok
us-west-1c-353 SERVICES.NTP.LATENCY 1.541
us-west-1c-353 SERVICES.RSYNC.STATUS ok
us-west-1c-353 SERVICES.NGINX.STATUS ok
1
  • pretty interesting to see it done in awk
    – Confu-Sed
    Jan 11, 2018 at 0:45
1

With gnu sed 4.4

sed -E '
/SERVER/{
  s/.* "([^"]*)"/\1/
  h
  d
}
s/[:"]//g
G
s/([^\n]*)\n(.*)/\2 \1/
' infile
2
  • The only thing gnu here is [^\n] and that is not needed since at any given time there are no more than two lines in the pattern space... which means s/(.*)\n(.*)/\2 \1/ will work equally well and make your solution more portable (i.e. it will work with any sed that supports ERE) Jan 10, 2018 at 11:47
  • nice way of doing it too, i should choose this answer too, but i used the awk one as it came in earlier to solve the problem
    – Confu-Sed
    Jan 11, 2018 at 0:49
0

I have used sed command to achieve the same and its works fine

  i=$(sed -n '/us-/p' filename  | awk -F ":" '{print $2}' | sed 's/"//g'  | sed -n '1p' | sed '/^$/d' | sed -r "s/\s+//g")

 j=$(sed -n '/us-/p' filename | awk -F ":" '{print $2}' | sed 's/"//g'  | sed -n '2p' | sed '/^$/d' | sed -r "s/\s+//g")

 sed -n "/$i/,/$j/p" filename  | sed '$d'|sed '1d' |sed "s/SERVER//g" | sed 's/"//g' | sed 's/://g'|sed "s/^/$i /g";sed -n "/$j/,/,/p" o.txt  | sed '1d' |sed "s/SERVER//g" | sed 's/"//g' | sed 's/://g'|sed "s/^/$j /g"

output

us-east-1e-421 SERVICES.SNMP.STATUS ok
us-east-1e-421 SERVICES.NTP.LATENCY 1.644
us-east-1e-421 SERVICES.POSTFIX.STATUS ok
us-west-1c-353 SERVICES.SNMP.STATUS ok
us-west-1c-353 SERVICES.NTP.STATUS ok
us-west-1c-353 SERVICES.NTP.LATENCY 1.541
us-west-1c-353 SERVICES.RSYNC.STATUS ok
us-west-1c-353 SERVICES.NGINX.STATUS ok
1
  • 2
    23 sed (+ 2 awk) invocations to do something that can be done with a single sed command ??? Jan 9, 2018 at 18:18

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .