LinuxQuestions.org
Visit Jeremy's Blog.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 08-10-2009, 09:26 AM   #1
SupermanInNY
Member
 
Registered: Jan 2006
Distribution: CentOS
Posts: 30

Rep: Reputation: 15
shell script to batch process-modify ip numbers in files.


Hi All,

I need a simple script that will help me batch process files.

Input and processing is:

/var/named/subdomain101.domain.tld.db
/var/named/subdomain102.domain.tld.db
/var/named/subdomain103.domain.tld.db
/var/named/subdomain104.domain.tld.db
/var/named/subdomain105.domain.tld.db
...

I have an IP of 1.2.3.4 in all of them and I need to
process them to change the ip to 2.2.2.2

Note, I want to process the files from a list in file.
however, I'm lazy , so I want to pull in just the subdomain
number.

102
103
104
etc...
I don't want to write the full name.
I want the script to loop and grab the number.
For now (and for the next 12 months) it is going to be 3 digit numbers, running up to 999.

Note: we have already converted the

/var/named/subdomain10.domain.tld.db (just ten)
/var/named/subdomain20.domain.tld.db (just twenty)

and we don't want to modify those.

I grabbed a conversion script from a diff prog, but cant' get it to work on "files in the directory", so batch processing it using an input file has not been explored yet.

PHP Code:
#!/bin/sh

#usage:
# $0 <oldip> <newip>


OLD_IP=$1
NEW_IP
=$2

swapfile
()
{
        if [ ! -
$]; then
                log 
"Cannot Find $1 to change the IPs. Skipping...";
                return;
        
fi

        TEMP
="perl -pi -e 's/(^|[\s.=\/:])${OLD_IP}([\s.>:])/\${1}${NEW_IP}\${2}/g' $1"
        
eval $TEMP;

}



for 
i in `ls /var/named/temp`; do
{

        if [ ! -
/var/named/temp/up10$i.domain.com.db ]; then
                
continue;
        
fi

        swapfile 
/var/named/temp/up10$i.domain.com.db


};
done
I appreciate any help on this.

Thanks,

-Sup.
 
Old 08-11-2009, 01:31 AM   #2
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Centos 7.7 (?), Centos 8.1
Posts: 18,030

Rep: Reputation: 2658Reputation: 2658Reputation: 2658Reputation: 2658Reputation: 2658Reputation: 2658Reputation: 2658Reputation: 2658Reputation: 2658Reputation: 2658Reputation: 2658
Can you give us an example of before and after a file has been processed, its not clear.
Also, if you're going to call perl anyway, why not just do it in perl?
 
Old 08-11-2009, 02:27 AM   #3
konsolebox
Senior Member
 
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,248
Blog Entries: 8

Rep: Reputation: 235Reputation: 235Reputation: 235
I'm not sure but it sounds like similar to this:
Code:
for a in $(<list); do
  test -e "/var/named/subdomain${a}.domain.tld.db" && \
    sed -i 's/1\.2\.3\.4/2\.2\.2\.2/g' "/var/named/subdomain${a}.domain.tld.db"
done
You can change the pattern to make it more precise.
 
Old 08-11-2009, 10:04 AM   #4
SupermanInNY
Member
 
Registered: Jan 2006
Distribution: CentOS
Posts: 30

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by konsolebox View Post
I'm not sure but it sounds like similar to this:
Code:
for a in $(<list); do
  test -e "/var/named/subdomain${a}.domain.tld.db" && \
    sed -i 's/1\.2\.3\.4/2\.2\.2\.2/g' "/var/named/subdomain${a}.domain.tld.db"
done
You can change the pattern to make it more precise.
Thanks for the quick reply.

I need a bit more guidance here:

I want to run the following:

./ipswap 1.2.3.4 2.2.2.2 filelist

(so 3 input parameters).

The zone files that I want to edit show like this:

PHP Code:
/var/named/temp # less up100.domain.com.db 

$TTL 14400
@       IN      SOA     ns1.domain.com.      hostmaster.up100.domain.com. (
                                                
2009071400
                                                14400
                                                3600
                                                1209600
                                                86400 
)

up100.domain.com.        14400   IN      NS      ns1.domain.com.
up100.domain.com.        14400   IN      NS      ns2.domain.com.

ftp     14400   IN      A       1.2.3.4
localhost       14400   IN      A       127.0.0.1
mail    14400   IN      A       1.2.3.4
pop     14400   IN      A       1.2.3.4
smtp    14400   IN      A       1.2.3.4
up100
.domain.com.        14400   IN      A       1.2.3.4
www     14400   IN      A       1.2.3.4

up100
.domain.com.        14400   IN      MX      10 mail



up100
.domain.com.        14400   IN      TXT     "v=spf1 a mx ip4:1.2.3.4 ~all" 
So now I need three inputs:

1. old IP
2. New IP
3. Files list


the file list will look like this:

up100.domain.com.db
up101.domain.com.db
up102.domain.com.db

and so on...

I want to have PATH= so that I can run this script on files that are stored in $PATH.

$PATH/up100.domain.com.db
$PATH/up101.domain.com.db
$PATH/up102.domain.com.db

PHP Code:
#!/bin/sh

#usage:
# $0 <oldip> <newip>


OLD_IP=$1
NEW_IP
=$2


for a in $(<list); do
  
test -"/var/named/temp/up${a}.domain.com.db" && \
    
sed -'s/${1}/${2}/g' "/var/named/test/up${a}.domain.com.db"
done 
Thanks for the help on this.

-Sup.
 
Old 08-11-2009, 10:29 AM   #5
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1198Reputation: 1198Reputation: 1198Reputation: 1198Reputation: 1198Reputation: 1198Reputation: 1198Reputation: 1198Reputation: 1198
Quote:
Originally Posted by SupermanInNY View Post
Code:
#!/bin/sh

#usage:
# $0 <oldip> <newip>


OLD_IP=$1
NEW_IP=$2


for a in $(<list); do
  test -e "/var/named/temp/up${a}.domain.com.db" && \
    sed -i 's/${1}/${2}/g' "/var/named/test/up${a}.domain.com.db"
done
A couple of observations to help on the way ...

Safer to use #!/bin/bash rather than #!/bin/sh 'cos then you know which shell your getting. /bin/sh is linked to a variety of shell's depending on the distro.

The single quotes around
Code:
's/${1}/${2}/g'
mean that it will be passed verbatim to sed, without the values of $1 and $2 being substituted as you intend -- and maybe you meant $OLD_IP and $NEW_IP. Double quotes will do what you want and the {} braces are not necessary.

I'll leave it to people who know better to comment on the expression to use with the sed s command to match an IP address. I netsearched unsuccessfully, looking for a robust expression; it's not easy because the "." means "any character" to sed and IP addresses can have 1-3 decimal digits between the "."s, each not beginning with 0 unless it's a network address.

Minor elegance and perfomance improvement, arguably at the price of legibility:
Code:
while read a ; do
  test -e "/var/named/temp/up${a}.domain.com.db" && \
    sed -i 's/${1}/${2}/g' "/var/named/test/up${a}.domain.com.db"
done < list
[pedantry]IP addresses can also be specified with leading 0s in which case they are interpreted as octal.[/pedantry]

Last edited by catkin; 08-11-2009 at 10:34 AM. Reason: 100s of titivations -- you should have seen it before!
 
Old 08-13-2009, 03:03 AM   #6
konsolebox
Senior Member
 
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,248
Blog Entries: 8

Rep: Reputation: 235Reputation: 235Reputation: 235
You can try this one. Not tested yet.

Code:
#!/bin/bash

showusageandexit() {
	echo "usage: $0 <oldip> <newip> <location_of_files> <listfile>"
	exit 1
}

shopt -s extglob

if [[ "$#" -ne 4 ]]; then
	echo "invalid number of arguments."
	showusageandexit
elif [[ "$1" != +([[:digit:]]).+([[:digit:]]).+([[:digit:]]).+([[:digit:]]) ]]; then
	echo "first argument is not a valid ip address."
	showusageandexit
elif [[ "$2" != +([[:digit:]]).+([[:digit:]]).+([[:digit:]]).+([[:digit:]]) ]]; then
	echo "second argument is not a valid ip address."
	showusageandexit
elif [[ ! test -d "$3" ]]; then
	echo "third argument is not a directory."
	showusageandexit
elif [[ ! test -f "$4" ]]; then	# -f might not be applicable sometimes.. change to -e if needed
	echo "fourth argument is not a file."
	showusageandexit
fi

oldipex=${1//./\\.} newipex=${2//./\\.} location=$3 listfile=$4

{
	while read -u 4 a; do
		if [[ -e "${location}/up${a}.domain.com.db" ]]; then
			echo "processing /var/named/test/up${a}.domain.com.db"
			sed -i "s/${oldipex}/${newipex}/g" "/var/named/test/up${a}.domain.com.db"
		else
			echo "file not found: ${location}/up${a}.domain.com.db"
			echo "press ctrl-c to cancel or any other key to continue . . ."
			read
		fi
	done
} 4< "$listfile"

Last edited by konsolebox; 08-14-2009 at 08:13 AM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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
any shell script 2 batch file tools? rosbur Linux - General 12 11-27-2018 12:20 PM
Shell script for reading a particular process contineously from process table vinaykori Linux - General 2 05-29-2009 06:52 AM
Change batch script to shell script alan.belizario Programming 5 03-31-2005 12:41 AM
Change batch script to shell script alan.belizario Linux - Software 1 03-30-2005 01:49 AM
Help w/ batch/shell script mikehlinuxquest Linux - General 5 09-13-2004 04:41 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 06:07 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