LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software
User Name
Password
Linux - Software This forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.

Notices


Reply
  Search this Thread
Old 01-23-2018, 07:09 PM   #1
mjl3434
Member
 
Registered: Sep 2003
Location: USA
Distribution: Ubuntu 20.04
Posts: 111

Rep: Reputation: 15
Script needed for deceptively difficult find and replace


Guys,

I'm trying to automatically do a find and replace in a bind config file, and I'm having a heck of a time coming up with a simple bash script that will do what I want. The bind config file has several sections like this:

Code:
view "name-of-view1" {
    match-clients {
        x.y.z.0/24;
    };
    forward only;
    include "/etc/bind/forwarder-file";

    ....
};
I want to find only a subset of the overall views, and then replace the include line with something else. For example suppose there are 10 views, "name-of-view1", "name-of-view2", ... all 10 with the exact same include line. Suppose I want to only change the include lines for the 3rd, 7th and 10th views to a different forwarder file.

Ideally (but not required) I would like to do this efficiently in only one pass. I have no doubt I can come up with a way to accomplish it in multiple passes, but I'm stuck on it trying to do it efficiently.
 
Old 01-23-2018, 07:58 PM   #2
keefaz
LQ Guru
 
Registered: Mar 2004
Distribution: Slackware
Posts: 6,552

Rep: Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872
With perl, a small script:
Code:
#!/usr/bin/perl

my %configs = (
	3 => 'config1.conf', 
	7 => 'another_config.conf', 
	10 => 'other.conf'
);

my $conf;

while(<>) {
	/^view.*?(\d+)/ and $conf = $configs{$1};
	s:(\s+include ")[^"].*(".*):$1/etc/bind/$conf$2: and $conf=undef if $conf;
	print;
}
Fill %configs hash with the specific view numbers and configuration filenames (don't include path)
name the script and chmod +x it
execute it like
Code:
./script.pl < /etc/named_config > /etc/named_config.new
edit: didn't fully read the question and the request about changing specific views so used a hash with numeric keys instead of array

Last edited by keefaz; 01-23-2018 at 08:31 PM.
 
Old 01-23-2018, 08:10 PM   #3
rigor
Member
 
Registered: Sep 2003
Location: 19th moon ................. ................Planet Covid ................Another Galaxy;............. ................Not Yours
Posts: 705

Rep: Reputation: Disabled
Hi mjl3434,

I have to say, I tend to think that bash might not be a great choice for such a task. Here's a trivial GAWK script that replaces the include file for each view. It's also rather trivial to modify it to contain a list of index of the views you would actually like to change, and then and in the further condition in the "if" statement. Alternatively, if you must use BASH, I believe a rather similar approach should work.

Code:
BEGIN   {
            view_include = "include \"/etc/bind/forwarder-file\";" ;
            rep_view_include = "include \"/etc/bind/new-forwarder-file\";" ;
        }

{
    if (  $0  !~  view_include  )
        print $0 ;
    else
        print "    "  rep_view_include ;
}
As a simple example:
Code:
#!/bin/bash

view_include='include "/etc/bind/forwarder-file";' ;

view_indexes=( 3  7  10 ) ;
include_files=( 'include "/etc/bind/forwarder-3-file";'   'include "/etc/bind/forwarder-7-file";'   'include "/etc/bind/forwarder-10-file";'  )  ;

read a_line
result=$? ;
include_count=1 ;
ra_index=0 ;

while  [[  $result  -eq  0  ]]
    do

        if [[  $a_line  =~  $view_include  ]]
            then

                if [[  $include_count  -eq  ${view_indexes[$ra_index]}  ]]
                    then
                        echo "    "  ${include_files[$ra_index]}
                        ra_index=$(( ra_index + 1 ))
                    else
                        /bin/echo $a_line
                fi

                include_count=$(( include_count + 1 ))

            else
                /bin/echo $a_line
        fi

        read a_line
        result=$?

    done
when fed a data file created from your example data file, but extended to contain 10 views, the script outputs a new config. file with the 3rd, 7th, and 10th includes replaced. It would just need a little tweaking to reproduce the whitespace as desired.

HTH.

Last edited by rigor; 01-23-2018 at 10:52 PM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Find and replace with a shell script abefroman Programming 5 03-10-2009 03:38 PM
Deceptively difficult? Jeebizz General 6 02-07-2009 10:33 AM
find and replace script UnixKiwi Programming 12 04-16-2007 11:08 PM
Help! Script or commanded needed to replace text in a file farmerjoe Programming 3 01-02-2005 05:59 PM
help! Script or command needed to replace text in a file. farmerjoe Linux - Newbie 2 01-02-2005 03:07 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Software

All times are GMT -5. The time now is 09:08 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration