awk printf format in columns

Hi all,

i have written this script:

awk -F';' '
BEGIN {
printf "\n"
printf "\n"
printf "\n"
printf "----------------------------------------------\n"
print " For test "
printf "----------------------------------------------\n"
test_200 = 0
test_300 = 0
test_500 = 0
test_1000 = 0
test_nok = 0
test_ok = 0
}
$5 == 200.0 {test_200++}
$5 == 300.0 {test_300++}
$5 == 500.0 {test_500++}
$5 == 1100.0 {test_1000++}
$6 !~ /SUCCESS/ {test_nok++}
$6 ~ /SUCCESS/ {test_ok++}
{count[$6]++}
NF>5&&!a[$6,$2]++{e[$6]++}
END {
for(j in count) printf "%-30s %-6d\n", j, count[j]
print ""
printf "%-30s %-6d\n", "test 200 ", test_200
printf "%-30s %-6d\n", "test 300 ", test_300
printf "%-30s %-6d\n", "test 500 ", test_500
printf "%-30s %-6d\n", "test 1000 ", test_1000
printf "\n"
printf "---------------------------------------------------\n"
printf "%-30s %-6d\n", "test unsuccessful ", test_nok
printf "%-30s %-6d\n", "test successful ", test_ok
printf "---------------------------------------------------\n"
for (i in e) printf "%-30s %-6d\n", i, e
}
' cdr

in order to process these logs:

25-04-2012;192.168.70.44;1254545454545110;300.0;SUCCESS
25-04-2012;192.168.70.31;1254545454545417;500.0;SUCCESS
30-04-2012;192.168.70.33;e;null;null;General_ERROR_23
30-04-2012;192.168.70.33;e;null;null;Failure
30-04-2012;192.168.70.33;e;null;null;Failure
30-04-2012;192.168.70.33;e;null;null;Failure
30-04-2012;192.168.70.33;e;null;null;Failure
30-04-201;192.168.70.34;e;null;null;ERROR_22
30-04-2012;192.168.70.37;e;null;null;INVALID_NUMBER
30-04-2012;192.168.70.10;e;null;null;Failure
30-04-2012;192.168.70.20;1254545454125417;1100.0;SUCCESS

The script works ok, but i want to format the output.

I want the output to be like this(2 tables, with headers and columns):

*******************************************
Message name | Number of errors | Numbers of unique IPs 
*******************************************
Failure ----------------5 ------------------2----------
ERROR_22
INVALID_NUMBER
SUCCESS
 
*******************************************
test_200 | test_300 | test_500 | test_1000
*******************************************
0 --------------1---------1------------ 0
 
etc etc....

I want everything to be formated in some way.
Maybe my script need also some improvement except formatting...i dont know.

Please, take a look at my script, i really need this for my work.

Thank you in advance,

Ervin

This 200/300/500/1000 is what? Would you rather count what's actually there, or just test for them to be any of those specific numbers? If you want to count each, do you want them all converted to integer first? And do you want it sorted?

Thank you for your reply.

200,300 , 500 etc are some recharge values for mobiles.
i want to count how many 300 or 500 ...etc values are in total.
25-04-2012;192.168.70.44;1254545454545110;300.0;SUCCESS
25-04-2012;192.168.70.31;1254545454545417;500.0;SUCCESS

in my example there are in total only one for 300, and only one for 500.
For 200 and 1100 there arent any recharge values.

BUT, in fact i want to order all the results in my script in columns like i have described above. Maybe the two "for " funcions have to be in only one funcion, so i can print thei results in columns with headers.

thank you very very much for helping!!!

About the "for" question --
When writing more than a one-liner, give variables clear names. You can see, you've count[] and e[] both using $6. So yes you can combine them.

*******************************************************************
        Message name |     Number of errors | Number of unique IPs
*******************************************************************
GENERAL_ERROR_23     |                    1 |                    1
ERROR_22             |                    1 |                    1
INVALID_NUMBER       |                    1 |                    1
FAILURE              |                    5 |                    2
*******************************************************************
           Recharged |      200 |      300 |      500 |     1100
                     |        0 |        1 |        1 |        1
*******************************************************************
test unsuccessful              8
test successful                3
*******************************************************************
#!/usr/bin/awk -f
BEGIN {
        FS=";"
        recharge[200]=recharge[300]=recharge[500]=recharge[1100]=0
}
NF==5 { success++ }
NF>5 { error++; $6=toupper($6); error_by_type[$6]++ }
# count unique ip:error
NF>5 && !ip_err[$6,$2]++ { error_by_ip[$6]++ }
# count recharge
(i=int($4+0.5)) && (i in recharge) { recharge++ }
END {
        # make line separator
        while (length(hr) < 67) hr=hr"*"
        print hr
        printf("%20s | %20s | %20s\n", "Message name", "Number of errors",
                "Number of unique IPs");
        print hr
        for (e in error_by_type)
                printf("%-20s | %20d | %20d\n", e, error_by_type[e],
                        error_by_ip[e])
        print hr
        printf("%20s | %8d | %8d | %8d | %8d\n", "Recharged", 200,300,500,1100)
        printf("%20s | %8d | %8d | %8d | %8d\n", "",
                recharge[200],recharge[300],recharge[500],recharge[1100])
        print hr
        printf("%-30s %-6d\n", "test unsuccessful ", error)
        printf("%-30s %-6d\n", "test successful ", success)
        print hr
}

I dont know what to say...
you are a life saver!!

Thank you very veryy much!!

GOD bless you!!

THANK YOU!

Hi all,

i want that the output of my awk script to be a file named log_$date.
For example the output of my script for today will be log_08052012.
How can i use the variable $date inside awk ?

Thank you for you time!

 
your awk command > log_`date +%d%m%Y`

thnx for reply

i tried it, but doesn't work.

instead of telling "doesnt work"

if you show your code, then we can help you

My code is

#!/usr/bin/awk -f
BEGIN {
FS=";"
recharge[200]=recharge[300]=recharge[500]=recharge[1100]=0
}
NF==5 { success++ }
NF>5 { error++; $6=toupper($6); error_by_type[$6]++ }
# count unique ip:error
NF>5 && !ip_err[$6,$2]++ { error_by_ip[$6]++ }
# count recharge
(i=int($4+0.5)) && (i in recharge) { recharge++ }
END {
# make line separator
while (length(hr) < 67) hr=hr"*"
print hr
printf("%20s | %20s | %20s\n", "Message name", "Number of errors",
"Number of unique IPs");
print hr
for (e in error_by_type)
printf("%-20s | %20d | %20d\n", e, error_by_type[e],
error_by_ip[e])
print hr
printf("%20s | %8d | %8d | %8d | %8d\n", "Recharged", 200,300,500,1100)
printf("%20s | %8d | %8d | %8d | %8d\n", "",
recharge[200],recharge[300],recharge[500],recharge[1100])
print hr
printf("%-30s %-6d\n", "test unsuccessful ", error)
printf("%-30s %-6d\n", "test successful ", success)
print hr
} >> log_`date +%d%m%Y` ??

Thanx :slight_smile:

it is your awk file code right ? --> i dont see any input file.

how you are triggering this file using awk ?

I give the input filename manually:

[root@localhost arrals]# ./script.sh filename