Search code examples
python-3.xshellawkcsh

How to take the data between two strings in a file Linux


I want to get the lines between forwarders { and }; those are IP address, below is the sample file which mimics my data..

// Red Hat BIND Configuration Tool
//
// THIS IS THE SLAVE DDNS SERVER -
//

// Currently running in chroot environment
// Prefix all file names below with /var/named/chroot
options {
        directory "/var/named";
        dump-file "/var/named/data/cache_dump.db";
        statistics-file "/var/named/data/named_stats.txt";
        recursion yes;
        check-names master ignore;
        check-names slave ignore;
        check-names respocope ignore;
        max-journal-size 2M;
        allow-query { any; };
        allow-update {
                key copdcop1.example.com.;
                key copdcop2.example.com.;
                key copdcop3.example.com.;
                key copdcop4.example.com.;
        };

        forward only;
        forwarders {
      192.168.174.131;     // cop-no1
      192.155.98.74;        // cop-jn1
      192.168.2.40;       // cop-sad1
      192.168.2.56;       // cop-s1
      192.43.4.70;        // cop-che1
      192.20.28.8;      // copdcop1
        };

Desired Result:

      192.168.174.131;     // cop-no1
      192.155.98.74;        // cop-jn1
      192.168.2.40;       // cop-sad1
      192.168.2.56;       // cop-s1
      192.43.4.70;        // cop-che1
      192.20.28.8;      // copdcop1

I'm okay with any solution either shell or python or awk.

I tried with sed but no luck..

sed -n '"/forwarders {"/,/"};"' dns.txt

However, below awk code works ..

awk '/forwarders {/{flag=1;next}/};/{flag=0}flag' dns.txt

Solution

  • EDIT: Since OP asked to have output into single line so adding following solution now.

    awk 'BEGIN{OFS=","} /}/{found=""} /forwarders {/{found=1} found && match($0,/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/){gsub(/ +/," ");val=(val?val OFS:"")$0}END{print val}'  Input_file
    

    OR non-one liner form of solution.

    awk '
    BEGIN{
      OFS=","
    }
    /}/{
      found=""
    }
    /forwarders {/{
      found=1
    }
    found && match($0,/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/){
      gsub(/ +/," ")
      val=(val?val OFS:"")$0
    }
    END{
      print val
    }'  Input_file
    

    OR as mentioned before too, to print anything inside forwarder block try:

    awk '/}/{found=""} /forwarders {/{found=1;next} found{gsub(/ +/," ");val=(val?val OFS:"")$0} END{print val}'  Input_file
    


    Could you please try following(considering that you only need to print IP addresses inside the tag).

    awk '/}/{found=""} /forwarders {/{found=1} found && match($0,/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/)'  Input_file
    

    In case forwarders tag you want to anything then try following.

    awk '/}/{found=""} /forwarders {/{found=1;next} found'  Input_file