LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Script question for BIND (https://www.linuxquestions.org/questions/programming-9/script-question-for-bind-4175704193/)

dupa 11-27-2021 10:01 PM

Script question for BIND
 
I need to or want to delete BIND DNS entries that are in File1 that match A records in File2. If the DNS entry has multiple records associated to it in File2, those need to remove too.

File1
Code:

car.example.com
truck.example.com
bike.example.com


File2
Code:

car    A    192.168.10.1
      A    192.168.10.10
      A    192.168.10.20
truck  NS  gtm1
      NS  gtm2
bike  A    192.168.10.5
      CNAME    trek.example.com


After the removal, I need or would like to add back new DNS entries into File2.
Code:

car.example.com      A    172.10.1.12
truck.example.com    A    172.10.1.15
bike.example.com    A    172.10.2.20

I tried a few grep. awk commands etc. I was able to remove the entry but not if the entry had multiple entries associated to it. However when I tried to start named.service it would fail.

Code:

grep -vwf file1 file2
Code:

grep -f <(cat file1 | sed 's/^/^/' ) file2

Racho 11-28-2021 05:13 AM

Try this:

To get the repeated domains list:
Code:

cut -d ' ' -f 1 file1 file2 |sort |uniq -d
To get the list of domains with more than one ip:

Code:

grep "[0-9\.][0-9\.]*, [0-9\.][0-9\.]*" file2
Before executing any command read it's man page to test that it is harmless and to know what it will do

Racho 11-28-2021 05:19 AM

Instead of the grep I suggested above, better just:
Code:

grep "," file2
because [0-9] is looking for numbers and wouldn't work with the line
bike.example.com 192.168.10.5, trek.example.com

NevemTeve 11-28-2021 07:57 AM

@OP as a start, please read this topic: https://www.linuxquestions.org/quest...gs-4175464257/

dupa 11-28-2021 08:00 AM

Quote:

Originally Posted by Racho (Post 6304875)
Try this:

To get the repeated domains list:
Code:

cut -d ' ' -f 1 file1 file2 |sort |uniq -d
To get the list of domains with more than one ip:

Code:

grep "[0-9\.][0-9\.]*, [0-9\.][0-9\.]*" file2
Before executing any command read it's man page to test that it is harmless and to know what it will do


Thanks for your reply. I realized that my file2 example wasn’t properly laid out as for what I’m dealing with. I updated it just now.

dupa 11-28-2021 09:08 AM

Quote:

Originally Posted by NevemTeve (Post 6304928)
@OP as a start, please read this topic: https://www.linuxquestions.org/quest...gs-4175464257/

Thank you. I believe I properly formatted to the guidelines now.

shruggy 11-28-2021 09:50 AM

Code:

grep -Fvwf <(cut -d. -f1 file1) file2

Racho 11-28-2021 10:30 AM

What about this?

Code:


awk  '{
if ($0!~"^[ \t].*" ) printf("\n")
else printf("---newlinemark---")
printf("%s", $0)
} END {printf("\n")}' file2 >file_tmp

ee=($(cut -d '.' -f 1 file1))
echo ${ee[@]}
for i in ${ee[@]} ; do aa="$aa -e \"^$i\""; done
echo "$aa" |(xargs grep -v $aa file_tmp )| sed 's/---newlinemark---/\n/g' >out
echo "$aa" |(xargs grep  $aa file_tmp )| sed 's/---newlinemark---/\n/g' >deleted
rm file_tmp

What it does is:
1) joins all lines of the same record in a temporary file (awk line)
2) reads file1 into a string and prepares the grep arguments: -e "^car" -e "^truck" -e "^bike"
3) writes all records without car truck bike recovering the newlines into the file out
4) writes the removed records into the file deleted
5) removes temporary file

replace ---newlinemark--- with something you will not find in any record

CyberIT 11-29-2021 10:17 AM

Quote:

Originally Posted by Racho (Post 6304973)
What about this?

Code:


awk  '{
if ($0!~"^[ \t].*" ) printf("\n")
else printf("---newlinemark---")
printf("%s", $0)
} END {printf("\n")}' file2 >file_tmp

ee=($(cut -d '.' -f 1 file1))
echo ${ee[@]}
for i in ${ee[@]} ; do aa="$aa -e \"^$i\""; done
echo "$aa" |(xargs grep -v $aa file_tmp )| sed 's/---newlinemark---/\n/g' >out
echo "$aa" |(xargs grep  $aa file_tmp )| sed 's/---newlinemark---/\n/g' >deleted
rm file_tmp

What it does is:
1) joins all lines of the same record in a temporary file (awk line)
2) reads file1 into a string and prepares the grep arguments: -e "^car" -e "^truck" -e "^bike"
3) writes all records without car truck bike recovering the newlines into the file out
4) writes the removed records into the file deleted
5) removes temporary file

replace ---newlinemark--- with something you will not find in any record



interesting approach. Thanks! I did notice that it did remove more than I wanted though. anything that started with car or truck or bike removed.

example: car1, car300, bikes, etc.

Im trying to just remove the ones that are named exactly the same, nothing more.

Racho 11-29-2021 02:39 PM

You are wellcome

Quote:

Im trying to just remove the ones that are named exactly the same, nothing more.
I see...

try this code
Code:

awk  '{
if ($0!~"^[ \t].*" ) printf("\n")
else printf("---newlinemark---")
printf("%s", $0)
} END {printf("\n")}' file2 >file_tmp

ee=($(cut -d '.' -f 1 file1))
echo ${ee[@]}
for i in ${ee[@]} ; do aa="$aa -e \"^$i \""; done

echo "$aa" |(xargs grep -v file_tmp )| sed 's/---newlinemark---/\n/g' >out
echo "$aa" |(xargs grep    file_tmp )| sed 's/---newlinemark---/\n/g' >deleted
rm file_tmp

I added a space in line 9 and removed $aa in grep of lines 11 and 12

dupa 12-01-2021 09:56 AM

Im kinda of newbie when coming to scripting ... I know some but no way an expert at it.

I could use some help on how to remove a host entry that could have (3) IP addresses then replace it with the proper (1) IP address.

I can remove 1 IP address but not if it has multiple.

I tried multiple ways and confused myself and not even sure which way was proper to remove one.

A little guidance would be much appreciated. Thank you!

shruggy 12-01-2021 10:33 AM

Sorry, I don't get what your problem is. You're matching the records not against IP addresses, but against host names, right? So what if a host has multiple IP addresses? It will be matched anyway.

E.g.
Code:

$ dig de.archive.ubuntu.com|grep ^\\w
de.archive.ubuntu.com.        597        IN        CNAME        ubuntu.mirror.tudos.de.
ubuntu.mirror.tudos.de.        92        IN        A        141.30.62.23
ubuntu.mirror.tudos.de.        92        IN        A        141.30.62.24
ubuntu.mirror.tudos.de.        92        IN        A        141.30.62.22
ubuntu.mirror.tudos.de.        92        IN        A        141.30.62.26
ubuntu.mirror.tudos.de.        92        IN        A        141.30.62.25

If you're matching against ubuntu.mirror.tudos.de, it will match all records.

It would be nice if you provided an example of what you tried to do, and what didn't work.

dupa 12-01-2021 10:43 AM

Quote:

Originally Posted by shruggy (Post 6305800)
Sorry, I don't get what your problem is. You're matching the records not against IP addresses, but against host names, right? So what if a host has multiple IP addresses? It will be matched anyway.

E.g.
Code:

$ dig de.archive.ubuntu.com|grep ^\\w
de.archive.ubuntu.com.        597        IN        CNAME        ubuntu.mirror.tudos.de.
ubuntu.mirror.tudos.de.        92        IN        A        141.30.62.23
ubuntu.mirror.tudos.de.        92        IN        A        141.30.62.24
ubuntu.mirror.tudos.de.        92        IN        A        141.30.62.22
ubuntu.mirror.tudos.de.        92        IN        A        141.30.62.26
ubuntu.mirror.tudos.de.        92        IN        A        141.30.62.25

If you're matching against ubuntu.mirror.tudos.de, it will match all records.

It would be nice if you provided an example of what you tried to do, and what didn't work.


good example. how would you remove all those entries at once?

I think if I dig for it first then remove it, that may do the trick.

shruggy 12-01-2021 11:16 AM

Quote:

Originally Posted by dupa (Post 6305803)
I think if I dig for it first then remove it, that may do the trick.

I guess the output of host could be easier to parse than dig's.

Well, I was of impression that your zone file is like in the Dyn example where the host name is repeated for each IP address.

However, if it's more similar to the example in RFC 1035 then I'd use range patterns:
Code:

sed '/^VENERA\>/,/^$/d'
or
Code:

awk '/^VENERA[ \t]/,/^$/{next}1'

MadeInGermany 12-05-2021 02:19 PM

\t in a character set is not standard.
I would go for
Code:

awk '/^VENERA[[:blank:]]/,/^$/{next}1'
Or
Code:

awk '$1=="VENERA"{d=1} !d; !NF{d=0}'


All times are GMT -5. The time now is 06:04 PM.