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. 
7
  • Apologies, but I have no idea how to format on this thing
    – bomahony
    Commented Jul 29, 2016 at 12:41
  • 2
    please provide some sample logs, and explain what exactly you are trying to do ?
    – Rahul
    Commented Jul 29, 2016 at 12:44
  • on echo $ja, try this: echo $(echo $ja). I dont know if it will help, but it removes new lines. Commented Jul 29, 2016 at 12:48
  • This is what log resolvers are for... Commented Jul 29, 2016 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. Commented Jul 29, 2016 at 13:16

1 Answer 1

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
5
  • s/sort -n/sort/ - you're sorting IP addresses. Commented Jul 29, 2016 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 :-) Commented Jul 29, 2016 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
    Commented Jul 29, 2016 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. Commented Jul 29, 2016 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
    Commented Jul 29, 2016 at 13:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .