1

I need to convert the following file example 1 to the file as appears on example 2

so it will print machine name and IP but only in case "name" appears before host_name

  • redhat03.rdns.com 10.10.29.66 not printed because "name" not appears before host_name

please advice what is the best way to do this convertion by awk or sed or perl one liners

example1

    "name" : "REDHAT",
    "host_name" : "linux01.rdns.com",
    "ip" : "10.10.29.61"
    "name" : "REDHAT",
    "host_name" : "linux02.rdns.com",
    "ip" : "10.10.29.62"
    "name" : "REDHAT",
    "host_name" : "linux03.rdns.com",
    "ip" : "10.10.29.63"
    "name" : "REDHAT",
    "host_name" : "redhat01.rdns.com",
    "ip" : "10.10.29.64"
    "name" : "REDHAT",
    "host_name" : "redhat02.rdns.com",
    "ip" : "10.10.29.65"
    "name" : "REDHAT",
    "host_name" : "redhat03.rdns.com",
    "ip" : "10.10.29.66"
    "host_name" : "redhat04.rdns.com",
    "ip" : "10.10.29.67"
    "name" : "REDHAT",
    "host_name" : "redhat05.rdns.com",
    "ip" : "10.10.29.68"
    "name" : "REDHAT",
    "host_name" : "redhat06.rdns.com",
    "ip" : "10.10.29.81"
    "name" : "REDHAT",
    "host_name" : "redhat07.rdns.com",
    "ip" : "10.10.29.82"
    "name" : "REDHAT",
    "host_name" : "redhat08.rdns.com",
    "ip" : "10.10.29.83"
    "name" : "REDHAT",
    "host_name" : "redhat09.rdns.com",
    "ip" : "10.10.29.84"

expected results

 linux01.rdns.com   10.10.29.61
 linux02.rdns.com   10.10.29.62
 linux03.rdns.com   10.10.29.63
 redhat01.rdns.com  10.10.29.64
 redhat02.rdns.com  10.10.29.65
 redhat03.rdns.com  10.10.29.66 
 redhat05.rdns.com  10.10.29.68
 redhat06.rdns.com  10.10.29.81
 redhat07.rdns.com  10.10.29.82
 redhat08.rdns.com  10.10.29.83
 redhat09.rdns.com  10.10.29.84
1
  • you meant redhat04.rdns.com is not printed Commented Jan 9, 2018 at 14:02

4 Answers 4

0

awk solution:

awk '/ip/ && NR-1==h_num && NR-2==n{ 
         r=h" "$3; gsub(/[,"]+/, "", r); print r 
     }
     /"host_name"/{ h_num=NR; h=$3 }
     /"name"/{ n=NR }' file

The output:

linux01.rdns.com 10.10.29.61
linux02.rdns.com 10.10.29.62
linux03.rdns.com 10.10.29.63
redhat01.rdns.com 10.10.29.64
redhat02.rdns.com 10.10.29.65
redhat03.rdns.com 10.10.29.66
redhat05.rdns.com 10.10.29.68
redhat06.rdns.com 10.10.29.81
redhat07.rdns.com 10.10.29.82
redhat08.rdns.com 10.10.29.83
redhat09.rdns.com 10.10.29.84
4
  • output should not inc;ude the " or , ( only hostnames and IP's Commented Jan 9, 2018 at 14:18
  • question why if I redirect the output to file - the I get shell-init: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory Commented Jan 9, 2018 at 14:33
  • example cat file | awk '/ip/ && NR-1==h_num && NR-2==n{ r=h" "$3; gsub(/[,"]+/, "", r); print r } /"host_name"/{ h_num=NR; h=$3 } /"name"/{ n=NR }' > new_file Commented Jan 9, 2018 at 14:34
  • @jango, this example cat file | awk ... is bad practice. Don't take that habit. Use awk '/ip/ && NR-1==h_num && NR-2==n{ r=h" "$3; gsub(/[,"]+/, "", r); print r } /"host_name"/{ h_num=NR; h=$3 } /"name"/{ n=NR }' yourfile > new_file. Besides, file is abstracted, you should specify your own actual file name Commented Jan 9, 2018 at 14:35
0

Following awk may help you in same.

awk -F' +|:|,|"' '/"name"/{flag=1;next} flag && /"host_name"/{val1=$(NF-2);next} flag && /"ip"/{print val1,$(NF-1);flag=""}'   Input_file
4
  • work partial because its print the redhat04.rdns.com 10.10.29.67 line , its not should to print it because "name" not exists before host_name Commented Jan 9, 2018 at 14:02
  • @jango, name should be REDHAT? or it should simply exist? Commented Jan 9, 2018 at 14:05
  • just need to check the word "name" if exist then need to print if name not exists then no need to print the next line hostname & ip Commented Jan 9, 2018 at 14:08
  • @jango, please check my edited code now and let me know if that helps you. Commented Jan 9, 2018 at 14:11
0

Please find the below sed oneliner to get the result. As checked its works fine

sed -n '/host_name/,+1p' filename  | awk -F ":" '{print $2}'  | sed 's/"//g' |sed "s/,//g" | sed "N;s/\n/ /g"

output

linux01.rdns.com  10.10.29.61
 linux02.rdns.com  10.10.29.62
 linux03.rdns.com  10.10.29.63
 redhat01.rdns.com  10.10.29.64
 redhat02.rdns.com  10.10.29.65
 redhat03.rdns.com  10.10.29.66
 redhat04.rdns.com  10.10.29.67
 redhat05.rdns.com  10.10.29.68
 redhat06.rdns.com  10.10.29.81
 redhat07.rdns.com  10.10.29.82
 redhat08.rdns.com  10.10.29.83
 redhat09.rdns.com  10.10.29.84
0

Here is another awk solution

awk -F'|:|,|"' '/"name"/{getline; printf $5; getline; print "  "$5}' file1
2
  • this does not provide any check if name line is followed by host_name and ip lines Commented Jan 9, 2018 at 14:23
  • @RomanPerekhrest you are correct. I took the liberty of providing the most simple command I could identify and still meet the constraints of the stated problem. I understood that the case would be that the "name line" would be the missing parameter and not any of the other lines based on jango's reply to RavinderSingh13 "just need to check the word "name" if exist then..." Commented Jan 9, 2018 at 14:48

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.