954,546 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

turn mb to gb!

hi,

i am totally stuck i need a script (that works in ksh under solaris 10) that takes the following output

d15 509MB c1t0d0s5
d13 7.0GB c1t0d0s3
d11 1.5GB c1t0d0s1
d10 10GB c1t0d0s0
d25 509MB c1t1d0s5
d23 7.0GB c1t1d0s3
d21 1.5GB c1t1d0s1
d20 10GB c1t1d0s0

and for the second column turn all values into MB and removes the MB and GB text. Some are already shown in mb and some are in GB. I think using awk would be the easiest but awk is not my strong point. The command i use to get the output in the first place is :

metastat -c | grep "s" | grep $DISK  | awk '{print $1,$3,$4}'\
         > ${UFSDISKSLICE}_${DISK}_${Date}


any help??

chris5126
Posting Pro in Training
415 posts since Feb 2006
Reputation Points: 38
Solved Threads: 15
 

can no one help??

chris5126
Posting Pro in Training
415 posts since Feb 2006
Reputation Points: 38
Solved Threads: 15
 

One of the biggest problems here, is getting the shell to handle floating point numbers. I'm not using / have access to a solaris machine, so I'm going strictly of bash in slackware.... but the shell doesn't handle floating point numbers. In a Perl script, I could knock this out, or in a C++ program, it would be a breeze... but doing this as a shell script, is an entirely different beast. Parsing the data with awk or sed would be alright, but converting the numbers is an entirely different challenge. In perl, it is pretty easy:

#!/usr/bin/perl

push @lines, "d15 509MB c1t0d0s5";
push @lines, "d13 7.0GB c1t0d0s3";
push @lines, "d11 1.5GB c1t0d0s1";
push @lines, "d10 10GB c1t0d0s0";
push @lines, "d25 509MB c1t1d0s5";
push @lines, "d23 7.0GB c1t1d0s3";
push @lines, "d21 1.5GB c1t1d0s1";
push @lines, "d20 10GB c1t1d0s0";

foreach $line (@lines) {
	($dcode, $unit, $drive) = split(/\s/, $line);

	if (substr($unit, (length($unit) -2), 2) eq "GB") {
		$unit = substr($unit, 0, length($unit) -2);
		$unit = ($unit * 1024); 		# // Convert To MB
	} else {
		$unit = substr($unit, 0, (length($unit) -2));
	}

	print "$dcode\t$unit\t$drive\n";
}
Comatose
Taboo Programmer
Team Colleague
2,910 posts since Dec 2004
Reputation Points: 361
Solved Threads: 215
 

Assuming data format:
d15 509MB c1t0d0s5
d13 7.0GB c1t0d0s3
d11 1.5GB c1t0d0s1
d10 10GB c1t0d0s0
d25 509MB c1t1d0s5
d23 7.0GB c1t1d0s3
d21 1.5GB c1t1d0s1
d20 10GB c1t1d0s0

For example purposes coming from datafile to awk and displaying to standard output. Modify to need.

awk '/s/ {
        if ( index($2, "GB") ) {
            $2 = sprintf("%10.2f", ($2*1024))
        }
        else {
            $2 = sprintf("%10.2f", $2)
        }
        print $0 
}' datafile

No need of calling grep to pipe only lines containing an s at column $3

/* output example
d15     509.00 c1t0d0s5
d13    7168.00 c1t0d0s3
d11    1536.00 c1t0d0s1
d10   10240.00 c1t0d0s0
d25     509.00 c1t1d0s5
d23    7168.00 c1t1d0s3
d21    1536.00 c1t1d0s1
d20   10240.00 c1t1d0s0
*/
Aia
Nearly a Posting Maven
2,392 posts since Dec 2006
Reputation Points: 2,224
Solved Threads: 218
 

Hi,

I get the following output:

d15       0.00 c1t0d0s5
d13       0.00 c1t0d0s3
d11       0.00 c1t0d0s1
d10       0.00 c1t0d0s0
d25       0.00 c1t1d0s5
d23       0.00 c1t1d0s3
d21       0.00 c1t1d0s1
d20       0.00 c1t1d0s0

Im using solaris 10 and the script is running with KSH could this be causing it?

chris5126
Posting Pro in Training
415 posts since Feb 2006
Reputation Points: 38
Solved Threads: 15
 
Hi, Im using solaris 10 and the script is running with KSH could this be causing it?

You get that result because sprintf is not receiving any value in column $2 that can convert into a decimal.
For debugging purposes substitute every line with a sprintf() call for just a print of $2 to see the result.

You could also post your script and help us to help you.

Aia
Nearly a Posting Maven
2,392 posts since Dec 2006
Reputation Points: 2,224
Solved Threads: 218
 

Hi,

To test it I was simply placing the data into a file in /tmp/datafile then the scripts looks like the following its also run from temp

#!/bin/ksh
awk '/s/ {
        if ( index($2, "GB") ) {
            $2 = sprintf("%10.2f", ($2*1024))
        }
        else {
            $2 = sprintf("%10.2f", $2)
        }
        print $0 
}' datafile

If I take out the sprintf line and just use print $2 at end of the script I get the following:

509MB
7.0GB
1.5GB
10GB
509MB
7.0GB
1.5GB
10GB

So sprint if getting the values however they still have either MB or GB on the end so therefore the sprintf statement wouldnt work would it?

chris5126
Posting Pro in Training
415 posts since Feb 2006
Reputation Points: 38
Solved Threads: 15
 

>So sprint if getting the values however they still have either MB or GB on the end so therefore the sprintf statement wouldnt work would it?

Yes, it would. sprintf() tries to read and convert any string to the format you give it.
To convince you run

echo "1.2GB" | awk '{print sprintf("$8.2f", $1)}'

...and watch the result.

Aia
Nearly a Posting Maven
2,392 posts since Dec 2006
Reputation Points: 2,224
Solved Threads: 218
 

hi,

Just tried that from the command line and I still get 0.00! any ideas what could be doing it?

chris5126
Posting Pro in Training
415 posts since Feb 2006
Reputation Points: 38
Solved Threads: 15
 

Hey Chris,

It looks like just a simple typo in Aia's reply. Just change $8.2f to %8.2f and you should get "1.20"

, Mike

eggi
Posting Pro in Training
400 posts since Oct 2007
Reputation Points: 102
Solved Threads: 47
 

hi,

I did notice the typo but even with it changed to % it still doesnt work the exact command im trying is :

root@testbench2:/tmp #echo "1.2GB" | awk '{print sprintf("%8.2f",$1)}'
    0.00

but if i take of the GB then it works:

echo "1.2" | awk '{print sprintf("%8.2f", $1)}'
    1.20


any ideas?

chris5126
Posting Pro in Training
415 posts since Feb 2006
Reputation Points: 38
Solved Threads: 15
 

>any ideas?
I am not running any version of Solaris so I don't know what's the "gotcha."
But if sprintf() is doing the job after the suffix "GB" is erased, let's do it.
Make an awk file that contains this:

#!/usr/bin/awk -f

$3 ~ /s/ {
    if ( index($2, "GB") ) {
        split($2, dissect, "G");
        $2 = sprintf("%8.2f", (dissect[1]*1024));
    }
    else {
        split($2, dissect, "M");
        $2 = sprintf("%8.2f", dissect[1]);
    }
    print $0
}


Then, call it with the input fileawk -f convert.awk data > outputdata
Where convert.awk is this awk file we talked about previously, data is the output to analyzed, and outputdata is the result file.Note: check that awk lives in the /usr/bin/awk. If not, change in awk file accordingly. Usually the command which awk will tell you.

Aia
Nearly a Posting Maven
2,392 posts since Dec 2006
Reputation Points: 2,224
Solved Threads: 218
 

This question has already been solved

Post: Markdown Syntax: Formatting Help
You