On Oct 31, 2008, at 3:53 PM, Justin T Pryzby wrote:

> On Fri, Oct 31, 2008 at 01:23:17PM -0700, Scott Haneda wrote:
>> I have an A record change that needs to happen across many zones. I
>> have the old ipand of course the new ip. Can someone help me with a
>> command to find and replace across multiple files please.
>>
>> I also will need to do a serial update as well, and that could be any
>> number and not cinsistant.

> I can suggest starting with something like this; note that sed -i
> modifies the files *in place* so work on a spare copy and diff
> afterwards.
>
> sed -i~ -se 's/\/\/' \
> -e "/^@[[:space:]]*[[:digit:]]*[[:space:]]*[A-Z]*[[:space:]]*/
> { :l; /)/ ! {N; b l}; /)/ ! {s/.*/unterminated SOA\n&/;q3}; s/(\
> ([[:space:]]*\)[0-9]*/\1`date +%Y%m%d`00/}" ZONEFILES
>
> Justin



Thanks justin, I ended up with a really dirty script that I hope to
get cleaner over time. I figure, most cases, is a string find and
replace, so this should cover it. My edge cases will be in the serial
number, as if it is not in the format of YYYYMMDDXX my script could
cause you issues. I can not reasonably see where someone would have a
TTL set to 10 digits long, so it should never match, but I suppose it
is still possible, and should be worked out.

A short description of what I am up to below:
Allow 8 seconds for the person to think about what they have done
I will add passed in arguments eventually, and remove this
Check user level to be sure they can read and write the files
Set your find and replace IP or string
Create a date format, increment the last serial as needed
( This will be a mess if you do not use serials that are date based )
Start setting up the regex
It finds, any whitespace, sets it to a pattern to replace with, then
any 0-9 digit, repeated 10 times, and the same any whitespace again,
set to a replace pattern as well.
I then simply swap in the correct bit and write it to a file, and move
the temp file into the live file.

I ran it, it works, I ran rndc, and a few others zone checks, nothing
complained. Thanks all, for the pointers on where to start.

echo "You have 8 seconds to abort, if you forgot to change something"

# Make sure the user is root
# Make sure only root can run our script
if [ "$(id -u)" != "0" ]; then
echo "This script must be run as root" 1>&2
exit 1
fi

find_string='71.193.228.248'
replace_string='71.237.136.207'
location=/var/named/hosts/masters
file_list=`grep -lr $find_string $location`
date=`date "+%Y%m%d01"`

echo "Finding: $find_string"
echo "Replacing: $replace_string"
sleep 2

regex_find='\([[:space:]]\)[0-9]\{10\}\([[:space:]]\)'
regex_replace="\1$date\2"

for file in $file_list
do
echo "About to find and replace in $file"
cat $file | sed "s/$find_string/$replace_string/g" | sed -e
"s/$regex_find/$regex_replace/g" > $file.new
cat $file.new
sleep 1
echo "Moving $file.new to $file"
mv $file.new $file
echo ""
echo ""
echo "Done"
done

--
Scott