2

using a dig command in a shell script and want to output into csv format flags and authority section

dig @ns1.hosangit.com djzah.com +noall +authority +comments

output

; <<>> DiG 9.8.3-P1 <<>> @ns1.hosangit.com djzah.com +noall +authority +comments
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64505
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 3, ADDITIONAL: 0
;; WARNING: recursion requested but not available

;; AUTHORITY SECTION:
djzah.com.  3600    IN  NS  ns3.eventguyz.com.
djzah.com.  3600    IN  NS  ns1.eventguyz.com.
djzah.com.  3600    IN  NS  ns2.eventguyz.com.

Expected output for csv is ( domain, flags (not always these three), authority section (could be 5) ):

djzah.com,qr,aa,rd,ns3.eventguyz.com,ns1.eventguyz.com,ns2.eventguyz.com

I was trying to use awk and/or sed but am having difficulty searching for a pattern like for the flags section ;; flags: (then use a space delimiter until you reach ;)

Then the Authority section, I assume you would search for ;; AUTHORITY SECTION: Then create an array and only use the last.

I don't know what I'm doing.

skamazin
  • 757
  • 5
  • 12
user3666682
  • 23
  • 1
  • 3

1 Answers1

1
#!/usr/bin/awk -f
BEGIN { OFS = "," }
/^;; flags:/ {
    sub(/;; flags: /, "")
    sub(/;.*$/, "")
    $1 = $1
    flags = "," $0
    next
}
/^;/ || NF < 5 { next }
!($1 in a) {
    keys[++k] = $1
}
{
    t = $5
    sub(/[.][ \t\r]*$/, "", t)
    a[$1] = a[$1] "," t
}
END {
    for (i = 1; i <= k; ++i) {
        key = keys[k]
        t = key
        sub(/[.][ \t\r]*$/, "", t)
        print t flags a[key]
    }
}

Usage:

dig @ns1.hosangit.com djzah.com +noall +authority +comments | awk -f script.awk

Test:

awk -f script.awk sample

Output:

djzah.com,qr,aa,rd,ns3.eventguyz.com,ns1.eventguyz.com,ns2.eventguyz
  • BEGIN { OFS = "," }: Every section in awk always run everytime a record is processed. BEGIN block only run once at start. This basically sets OFS to ,.
  • /^;; flags:/ matches ;; flags:. The section that is presented by it basically extracts the flags from the record (line). The sub commands basically remove unnecessary parts from the record. $1 = $1 just makes sure $0 is updated with OFS. flags = "," $0 assigns the now comma-separated flags into flags variable. next makes awk jump to the next record.
  • /^;/ || NF < 5 { next } basically makes awk skip unnecessary lines.
  • !($1 in a) { keys[++k] = $1 } if $1 e.g. djzah.com. is first encountered, add to keys array.
  • { t = $5; sub(/[.][ \t\r]*$/, "", t); a[$1] = a[$1] "," t } adds the value of the 5th column e.g. ns3.eventguyz.com to the collection with the leading . removed.
  • When processing is finished, END block executes. It iterates through the keys found and prints the data bound to it.
konsolebox
  • 72,135
  • 12
  • 99
  • 105
  • 1
    Would you mind commenting your `awk` script. The OP could probably learn a lot from it. – skamazin Aug 04 '14 at 12:01
  • @user3666682 It would be nice if you give more samples in which it doesn't work. – konsolebox Aug 04 '14 at 12:54
  • Thank You for the script. Would love to learn how it works. As skamazin said, could you add comments to help me understand how everything is happening? It does work great by the way, just wish I knew how its working. :) – user3666682 Aug 04 '14 at 13:22
  • @user3666682 Added some comments on it. – konsolebox Aug 04 '14 at 13:45
  • Awesome, thank you very much for helping. Hopefully I catch on sooner than later. :) – user3666682 Aug 04 '14 at 13:46
  • @user3666682 It's always very helpful reading[The GNU Awk User’s Guide](http://www.gnu.org/software/gawk/manual/gawk.html) even just once. – konsolebox Aug 04 '14 at 13:54
  • Thanks again konsolebox. I'll look through it and see if I can figure out my issue. It appears the script skips over domains that either don't have all the flags (just qr rd) OR maybe its because they have no authority servers... not sure yet. – user3666682 Aug 04 '14 at 19:25