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
  • you meant redhat04.rdns.com is not printed – RomanPerekhrest Jan 9 '18 at 14:02
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
  • output should not inc;ude the " or , ( only hostnames and IP's – jango Jan 9 '18 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 – jango Jan 9 '18 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 – jango Jan 9 '18 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 – RomanPerekhrest Jan 9 '18 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
  • 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 – jango Jan 9 '18 at 14:02
  • @jango, name should be REDHAT? or it should simply exist? – RavinderSingh13 Jan 9 '18 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 – jango Jan 9 '18 at 14:08
  • @jango, please check my edited code now and let me know if that helps you. – RavinderSingh13 Jan 9 '18 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
  • this does not provide any check if name line is followed by host_name and ip lines – RomanPerekhrest Jan 9 '18 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..." – rcjohnson Jan 9 '18 at 14:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.