0

I am currently writing something to parse some apache logs, yet the system command seems to be putting itself above print. Haven't done a whole lot with awk, so it could be something very simple.

IFS=$'\n' 
for ja in `cat test.apache.access_log | awk '{print $1}' | sort -n | uniq -c | sort -rn | head -3`
do 
echo $ja|awk '{print "Count\tIP\t\tNSLookup"}{print $1"\t",$2,"\t\t",system("nslookup " $2"|grep name")}'
done

What I get :

Count   IP              NSLookup
RR.ZZ.YY.XX.in-addr.arpa      name = ja.server.net.
241      XX.YY.ZZ.RR           0 

What I would like to see is:

Count   IP              NSLookup
241      XX.YY.ZZ.RR          RR.ZZ.YY.XX.in-addr.arpa      name = ja.server.net. 
  • Apologies, but I have no idea how to format on this thing – bomahony Jul 29 '16 at 12:41
  • 2
    please provide some sample logs, and explain what exactly you are trying to do ? – Rahul Jul 29 '16 at 12:44
  • on echo $ja, try this: echo $(echo $ja). I dont know if it will help, but it removes new lines. – Luciano Andress Martini Jul 29 '16 at 12:48
  • This is what log resolvers are for... – Satō Katsura Jul 29 '16 at 13:13
  • 1
    If you have to use awk then note that system() will send output to STDOUT and the return code is the result (that's why you get a 0 on your line). If you want to capture this for processing then you need to do a system(..) | getline name ; print "..."name type call. – Stephen Harris Jul 29 '16 at 13:16
2

Your script need to be reordered a little and awk do not need at all

echo -e 'Count\tIP\tNSLookup'
while read count line ; do
    echo -ne "$count\t$line\t"
    nslookup $line | grep name
done < <(cut -d' ' -f1 test.apache.access_log | sort | uniq -c | sort -rn | head -3)

And sure it can be done by awk only

awk '
    BEGIN{
        OFS="\t"
        print "Count", "IP", "NSLookup"
    }
    {
        A[$1]++
    }
    END{
        for(a in A){
            i = 3
            while(i > 0 && A[a] > A[B[i]]){
                B[i+1] = B[i]
                i--
            }
            B[i+1] = a
        }
        for(b=1; b<4; b++){
            "nslookup "B[b]" | grep name" | getline ns
            print A[B[b]], B[b], ns
        }
    }
    ' test.apache.access_log
  • s/sort -n/sort/ - you're sorting IP addresses. – Satō Katsura Jul 29 '16 at 13:13
  • The sort doesn't need the -n because we just need a consistent ordering, so uniq -c can count unique lines; we re-order with sort -rn afterwards. It could be any data; doesn't matter :-) – Stephen Harris Jul 29 '16 at 13:15
  • @StephenHarris @SatoKatsura Yes, and I see that OP need 1.100.1.1 after 1.99.1.1 therefore -n or -V should be in – Costas Jul 29 '16 at 13:24
  • No, the OP wants the output in "most frequently used first" order; that's what the final sort -rn does. The intermediate part of the pipeline ordering doesn't matter. – Stephen Harris Jul 29 '16 at 13:36
  • Folks, thanks for all the help. Ill have a quick look at this in a little while and confirm it works, which I assume it wil, and then close off the question. Thanks for all the help folks! – bomahony Jul 29 '16 at 13:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.