Percentage calculation


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Percentage calculation
# 1  
Old 10-21-2015
Percentage calculation

Hi,

I have a text file in below format.
I trying to find a solution for finding percentage used for each of the NAMEs.

Code:
Directory    ALLOCATED USED
NAME1      93MB        93KB   
NAME2      25G        62K     
NAME3      14G        873M    
NAME4      25G        62K     
NAME5      20G        10.0G    
NAME6      16.1M      16.1M    
NAME7      120G       78.8G    
NAME8      100G       71.8G    
NAME9      130G       57.2G    
NAME10      300G       166G     
NAME11      20G        31KB      
NAME12      100G       52.4G    
NAME13      275G       126G     
NAME14      300T       109G

I tried several awk solution like
Code:
 awk '{FS="|"; OFS="|"; if (NR<=2) {print} else {print $0 " | " $2/$3*100}}'

but none worked due to the different formats like KB,MB,GB ,TB.
Is there anyway i can do it one line ? Also I may not be able to recalculate the data in one format. Smilie

Last edited by ctrld; 10-21-2015 at 12:09 PM..
# 2  
Old 10-21-2015
Is K 1000 or 1024?

Is KB 1000 or 1024?

Are any multipliers other than K, M, G, and T possible?

Last edited by Don Cragun; 10-21-2015 at 12:11 PM.. Reason: Add request for clarification of list of multipliers.
This User Gave Thanks to Don Cragun For This Post:
# 3  
Old 10-21-2015
Sorry its typo read it as KB, I have corrected it in original post. And its 1024.
# 4  
Old 10-21-2015
Your code implied that your input file uses | as the field separator, but your sample input uses whitespace as the input field separator and you didn't show us any sample output. The following code uses whitespace as the input field separator and | as the output field separator. And, I still see lots of "human readable" values that don't end with B. The following code seems to do what you want (treating KB and K, MB and M, ... as synonyms). I greatly prefer readable to 1-liner, but as with any awk program you can convert it to a single line if you want to...
Code:
awk '
BEGIN {	ec = 0
	m["B"] = 1
	m["K"] = m["KB"] = 1024
	m["M"] = m["MB"] = 1024 ** 2
	m["G"] = m["GB"] = 1024 ** 3
	m["T"] = m["TB"] = 1024 ** 4
	OFS = "|"
}
function mult(f,	mul, num, str) {
	if(match(f, /[[:upper:]]+/) == 0) {
		printf("No multiplier in %s in line %d for %s\n", f, NR, $1)
		ec = 1
		return 1
	}
	num = substr(f, 1, RSTART - 1)
	str = substr(f, RSTART)
	if(str in m) 
		return num * m[str]
	printf("Multiplier %s in line %d for %s unknown\n", str, NR, $1)
	ec = 1
	return 1
}
FNR == 1 {
	$4="%Used"
	print
	next
}
{	$4 = sprintf("%.2f", mult($3) * 100 / mult($2))
	print
}
END {	exit ec
}'

As always, if you want to try this on a Solaris/SunOS system, change awk to /usr/xpg4/bin/awk or nawk.

With your sample input plus the following line added to the end:
Code:
NAME15	    100FB	99

it produces the output:
Code:
Directory|ALLOCATED|USED|%Used
NAME1|93MB|93KB|0.10
NAME2|25G|62K|0.00
NAME3|14G|873M|6.09
NAME4|25G|62K|0.00
NAME5|20G|10.0G|50.00
NAME6|16.1M|16.1M|100.00
NAME7|120G|78.8G|65.67
NAME8|100G|71.8G|71.80
NAME9|130G|57.2G|44.00
NAME10|300G|166G|55.33
NAME11|20G|31KB|0.00
NAME12|100G|52.4G|52.40
NAME13|275G|126G|45.82
NAME14|300T|109G|0.04
No multiplier in 99 in line 16 for NAME15
Multiplier FB in line 16 for NAME15 unknown
NAME15|100FB|99|100.00

and exits with exit code 1. When run with just your sample input, the last three lines shown above are not printed and it exits with exit code 0.

Last edited by Don Cragun; 10-21-2015 at 03:07 PM.. Reason: Fix typo: s/codet/code/
This User Gave Thanks to Don Cragun For This Post:
# 5  
Old 10-21-2015
Hello ctrld,

If you need only row number and the percentage then following may help you in same.
Code:
awk 'function check(var){match(var,/M|MB/);A=substr(var,RSTART,RLENGTH);if(A){sub(/M|MB/,X,var);val=var * 1024;return val;val=""};match(var,/G|GB/);B=substr(var,RSTART,RLENGTH);if(B){sub(/G|GB/,X,var);val=var * 1024 * 1024;return val;val="";};match(var,/T|TB/);A=substr(var,RSTART,RLENGTH);if(A){sub(/T|TB/,X,var);val=var * 1024 * 1024 * 1024;return val;val=""};match(var,/K|KB/);D=substr(var,RSTART,RLENGTH);if(D){sub(/K|KB/,X,var);val=var;return val;val="";};} NR>1{for(i=2;i<=NF;i++){A=check($i);Q[NR]=Q[NR]?Q[NR] OFS A:A;}k++} END{print "ROW" OFS "PERCENTAGE";for(i=2;i<=k+1;i++){split(Q[i], E," ");print i OFS E[2]/E[1] * 100}}' OFS="\t"  Input_file

Output will be as follows.
Code:
ROW     PERCENTAGE
2       0.0976562
3       0.000236511
4       6.08956
5       0.000236511
6       50
7       100
8       65.6667
9       71.8
10      44
11      55.3333
12      0.00014782
13      52.4
14      45.8182
15      0.0354818

EDIT: Adding a non one-liner form of solution for same now.
Code:
awk 'function check(var)        {
                                        match(var,/M|MB/);
                                        A=substr(var,RSTART,RLENGTH);
                                        if(A){
                                                sub(/M|MB/,X,var);
                                                val=var * 1024;
                                                return val;
                                                val=""
                                             };
                                        match(var,/G|GB/);
                                        B=substr(var,RSTART,RLENGTH);
                                        if(B){
                                                sub(/G|GB/,X,var);
                                                val=var * 1024 * 1024;
                                                return val;
                                                val="";
                                             };
                                        match(var,/T|TB/);
                                        C=substr(var,RSTART,RLENGTH);
                                        if(C){
                                                sub(/T|TB/,X,var);
                                                val=var * 1024 * 1024 * 1024;
                                                return val;
                                                val=""
                                             };
                                        match(var,/K|KB/);
                                        D=substr(var,RSTART,RLENGTH);
                                        if(D){
                                                sub(/K|KB/,X,var);
                                                val=var;
                                                return val;
                                                val="";
                                             };
                                }
      NR>1                      {
                                        for(i=2;i<=NF;i++){
                                                                A=check($i);
                                                                Q[NR]=Q[NR]?Q[NR] OFS A:A;
                                                          };k++
                                }
      END                       {
                                        print "ROW" OFS "PERCENTAGE";
                                        for(i=2;i<=k+1;i++){
                                                                split(Q[i], E," ");
                                                                print i OFS E[2]/E[1] * 100
                                }
                                }
 ' OFS="\t" Input_file

Thanks,
R. Singh

Last edited by RavinderSingh13; 10-21-2015 at 01:45 PM.. Reason: Added a non one-liner form of solution now
This User Gave Thanks to RavinderSingh13 For This Post:
# 6  
Old 10-21-2015
Try also (no error checking included):
Code:
awk     '
BEGIN           {ENG = "BKMGT"
                 for (i=split (ENG, UN, ""); i>0; i--) EXP[UN[i]]=i-1
                }

function NBR(NUMSTR)    {NUMSTR=toupper(NUMSTR)
                         match (NUMSTR, "[" ENG "]")
                         return substr(NUMSTR,1,RSTART-1) * 1024 ^ EXP[substr(NUMSTR, RSTART,1)]
                        }

NR==1           {print $0, "percent"
                 next
                }

                {printf "%s\t %.2f%%\n", $0, 100 * NBR($3) / NBR($2)
                }
' OFS="\t" file

This User Gave Thanks to RudiC For This Post:
# 7  
Old 10-21-2015
Quote:
Originally Posted by RavinderSingh13
Hello ctrld,

If you need only row number and the percentage then following may help you in same.
... ... ...
Code:
awk 'function check(var)        {
... ... ...
                                        if(A){
                                                sub(/M|MB/,X,var);
                                                val=var * 1024;
                                                return val;
                                                val=""
                                             };
... ... ...

Hi Ravinder,
Nice script.

Note, however, that the line shown in red (which occurs a few times in your script isn't needed and can't be executed. Commands in a code block following a return command will never be reached.
These 2 Users Gave Thanks to Don Cragun For This Post:
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Help with awk percentage calculation from a file

i have a file say test with the below mentioned details Folder Name Total space Space used /test/test1 500.1GB 112.0 GB /test/test2 3.2 TB 5TB /test/test3 3TB 100GB i need to calculate percentage of each row based on total space and space used and copy... (9 Replies)
Discussion started by: venkitesh
9 Replies

2. Shell Programming and Scripting

Calculate Percentage

Hello, Ive got a bunch of numbers here e.g: 6065 6094 6348 6297 6161 6377 6338 6290 How do I find out if there is a difference between 10% or more between one of these numbers ? I am trying to do this in Bash.. but no luck so far.. Does anyone have an Idea ?? Thanx, - Pascal... (9 Replies)
Discussion started by: denbekker
9 Replies

3. Shell Programming and Scripting

Need to monitor OS in percentage

Hi, I am looking for generic commands / scripts that could run across platforms especially on HP Itanium boxes to give me % of free OS parameters For eg: Free Total Memory RAM : 20 % Free Total Swap Memory: 35% Free Total CPU utilisation: 44% Free Disk Space: /appl = 55%... (5 Replies)
Discussion started by: mohtashims
5 Replies

4. Shell Programming and Scripting

Percentage calculation

i am trying to get percentage : but not able to do it: i tried : x=1 y=2 z=`expr $x/$y*100` it is not giving me result can u pls help on this (4 Replies)
Discussion started by: Aditya.Gurgaon
4 Replies

5. Shell Programming and Scripting

Percentage Calculation in Decimal

Hi, I have two variable and I need to calculate the percentage of them. Example: (b-a)*100/b How can I do it? I need to do it till 2 decimal point. (16 Replies)
Discussion started by: Anupam_Halder
16 Replies

6. Shell Programming and Scripting

awk/sed percentage calculation

Hi all i have a text file with columns delimited with , 2010-08-18,10,24,.09751,39,7,14872,26732 . . . i would to add a extra column in the end with percentage calculation of columns 5 and 8 ie (39/26732)*100 so the output must look like ... (6 Replies)
Discussion started by: posner
6 Replies

7. UNIX for Dummies Questions & Answers

percentage

How to calculate percentage of two values in unix. (5 Replies)
Discussion started by: venkatesht
5 Replies

8. Shell Programming and Scripting

How can i calculate percentage ??

i have 3 files like total.dat=18 equal.dat=14 notequal.dat=16 i need find the equal percentange means: equalpercentage = ($equal.dat / $total.dat * 100) How i can do this ? I tried some of the answers to calculate the percentage in this forums.but it couldn't worked.Some one please... (6 Replies)
Discussion started by: bobprabhu
6 Replies

9. Shell Programming and Scripting

awk percentage

how would you calculate percentage by per line? Given a column of 16 lines, grab each line and divide it by the sum of the entire column and multiply by 100? thanks ... (8 Replies)
Discussion started by: rockiefx
8 Replies

10. Shell Programming and Scripting

percentage by line

hi, I am new to awk.. and getting used to the scripts. I have a small data set 5 coulms.. 16 rows. 1) I am trying to remove the percentages of each line of colum 3..like first line divided the sum of colum 3 divided by 100 and print it out. removing hte percentages of each line I would really... (3 Replies)
Discussion started by: rockiefx
3 Replies
Login or Register to Ask a Question