converting a variable into something readable

Hi all,

I’m trying to get the size of a user’s Documents folder and if it’s over 10 gig, say it’s over 10 gig and if its under that, life continues.

I know I can use physical size of but I need to exclude certain file types so I’m using the du command with the -I option.

I would like the display dialog to return a result that is a bit more user friendly then 8.23444E9 and I can’t find the magic sequence. I’ve tried making it as real, as integer, as Unicode Text, which BTW, would be fun but totally unreadable.

Can anyone give me some guidance, or a better way of doing this?

Thank you in advance!
Joy



set local_document_size to do shell script ("du -sI *.dmg -I *.iso -I *.img -I *.cdr -I *.pkg -I *.mpkg -I *.app -I *Microsoft* ~/Documents | cut -f1") as number


if local_document_size > 8.38E+7 then
	set backup_answer to display dialog "The size of your Documents folder is" & local_document_size & "GIGS.  The backup will take awhile.  Did you want to continue setting up the backup to the network?" buttons {"Yes", "No"} default button "Yes"
	if button returned of backup_answer is "Yes" then
		display alert "Cool"
	end if
end if

set gigas to ((local_document_size/10000000) as integer)/100

It’s hacky, but:

8.38E+7 as miles as string --> "83800000"

You can change miles to any unit AS supports.

You can also use ASAObjC Runner:

tell application "ASObjC Runner"
	format number 8.38E+7 format "#,###" --> "83,800,000"
end tell

What do you get if you don’t coerce the shell script result to number? If the text is in the form you want, then you could use that instead, coercing it to number only for the comparison with 8.38E+7:

set local_document_size to do shell script ("du -sI *.dmg -I *.iso -I *.img -I *.cdr -I *.pkg -I *.mpkg -I *.app -I *Microsoft* ~/Documents | cut -f1")

if (local_document_size as number) > 8.38E+7 then
	set backup_answer to display dialog "The size of your Documents folder is" & local_document_size & "GIGS."
	-- etc.
end if

However, the “du” result isn’t in GIgabytes but in 512-byte allocation blocks. You could set the environment variable BLOCKSIZE to your favourite interpretation of Gigabyte, or use “du”'s -g option to count in 1073741824-byte blocks, but the result would be “1” for each Gigabyte or part thereof. To convert a 512-byte-block count to Gigabytes, I reckon mouramartins’s code should be:

set local_document_size to do shell script ("du -sI *.dg -I *.iso -I *.img -I *.cdr -I *.pkg -I *.mpkg -I *.app -I *Microsoft* ~/Documents | cut -f1")

-- "Gigabyte" = 10 ^ 9 bytes:
set gigas to ((local_document_size * 512 / 1.0E+7) as integer) / 100 -- Dividing by 1.0E+7 is equivalent to dividing by 1.0E+9 then multiplying by 100. 
-- Or "Gigabyte" = 2 ^ 30 bytes:
set gigas to ((local_document_size * 512 / 1.073741824E+7) as integer) / 100 -- Simile.

Edit: Exponents corrected as per DJ Bazzie Wazzie’s comment three posts down.

Incidentally, going back to coercing shell script results to number, ‘do shell script’ has an ‘as’ parameter which you don’t want to use here. You need an AppleScript coercion. To get this, you have to parenthesise the ‘do shell script’ command so that the ‘as’ isn’t interpreted as part of it:

set local_document_size to (do shell script ("du -sI *.dmg -I *.iso -I *.img -I *.cdr -I *.pkg -I *.mpkg -I *.app -I *Microsoft* ~/Documents | cut -f1")) as number

Hello.

I wasn’t totally sure of the new definitions of the GB so I googled it, and as one article stated. “when you are buying a 100GB drive, you get 107 (in the understanding that the vendor uses Apple’s metrics for a GB)” :smiley:

I think the new way of specifying a GB makes a whole lot of sense, since that is what the user sees. Even the late Brian W. Kernighan found it to be sensible, having first been baffled by the size of the music collection on his ipod.

I found a nice readup on the subject here

Thank you ALL!!! Nigel’s suggestion worked!

I think that Nigels forgot the complete code ((n * 100 as integer) / 100) to get 2 decimals after the decimal mark. the values are 100 times too small.

set local_document_size to do shell script ("du -sI *.dg -I *.iso -I *.img -I *.cdr -I *.pkg -I *.mpkg -I *.app -I *Microsoft* ~/Documents | cut -f1")

-- "Gigabyte" = 10 ^ 9 bytes:
set gigas to ((local_document_size * 512 / 1.0E+7) as integer) / 100
-- Or "Gigabyte" = 2 ^ 30 bytes:
set gigas to ((local_document_size * 512 / 1.073741824E+7) as integer) / 100

Once you’re invoking a shell you can do calculations easily with bc. I’m using run script, instead of an ‘as number’ coercion for languages that uses a comma as decimal separator like in my language.

#when a K = 1024
set local_document_size to run script (do shell script "bc <<< \"scale=3;$(du -sI *.dmg -I *.iso -I *.img -I *.cdr -I *.pkg -I *.mpkg -I *.app -I *Microsoft* ~/Documents | cut -f1) / (1024 ^ 3) * 512\" | xargs printf \"%.2f\"")
#when an K is 1000
set local_document_size to run script (do shell script "bc <<< \"scale=3;$(du -sI *.dmg -I *.iso -I *.img -I *.cdr -I *.pkg -I *.mpkg -I *.app -I *Microsoft* ~/Documents | cut -f1) * 512 / (10 ^ 9)\" | xargs printf \"%.2f\"")

p.s. The scale property in bc cuts of decimals and doesn’t round the up if needed. I needed to use printf to do the rounding correctly

Hello.

I am far to tired too do the math right now, at the “Z” level, but it beats me that in order to do “Apple Metrics” you should disregard block sizes of 512k and use 500 instead in order to make the metrics work out correctly.

Because this is not just for GB’s; they reckon 1K is 1000 and not 1024 as well, doing the same metrics.

Wow. I love this group!

I was thinking the math was going to be a bit complex. Way to complex for my brain, but I was also wondering why the numbers weren’t adding up.

Thank you DJ Bazzie Wazzie and all who responded! Perfect!!

When I get block sizes of 512 bytes I need to multiply the value with 512 to get the value in bytes first. Then you can divide it with 1024 ^ 3 or 10 ^ 9 to whatever your likings.

Yes I did. Thanks. I’ve now corrected the offending script above. :rolleyes:

FWIW, OS X 10.8 has an API for producing strings the way the Finder does it:

script convertBytes
	set theValue to current application's NSApp's convertedValue()
	return current application's NSByteCountFormatter's stringFromByteCount_countStyle_(theValue, 0) -- use 1 for 1024
end script

tell application id "au.com.myriad-com.ASObjC-Runner" -- ASObjC Runner.app
	set bytesString to run the script {convertBytes} converting 123456789 with response --> "123.5 MB"
	set bytesString to run the script {convertBytes} converting 1.23456789123E+10 with response --> "12.35 GB"
	set bytesString to run the script {convertBytes} converting 123 with response --> "123 bytes"
end tell

Hello.

This is my version, a stand along tiny utility for doing the task, save it as dusum.c in a directory, then type: make dusum, this works if you have Developer tools installed!

[code]#include <stdio.h>

int main( int argc, char **argv)
{
if (argc>1) {
fprintf(stderr,“dusum usage: du |dusum\n”) ;
return 1 ;
}
long double aLongDouble, theSum=0;
char digest[256];
while (!feof(stdin)) {
fscanf(stdin,“%Lf%s\n”,&aLongDouble,digest );
theSum+=aLongDouble ;
}
long double gigas = (long double)(theSum*512)/1000000000 ;
fprintf(stdout,“%.2Lf\n”,gigas);
return 0;
}[/code]
When dusum resides either in a path or with a path specified in front of it, you should be able to amened it at the end of the du statement, and get a result formatted as GB’s with two decimals back.

Edit
I couldn’t sleep as it nagged me that I may have had used a to small container for the number of blocks in a file, testing it originally in a folder where it was made. It is supposed to work properly now.

If not for anything else, this should serve as a demonstration of how quick it is to create a small c-program, once you have the tools installed.

C-programs like this are far faster to create if you know your way around with the scanf function (man -s3 scanf) and printf (man -s3 printf), than anything else. That it: when it comes to summing up stuff from standard input, where you would use bc or awk to perform the same. The important thing is to digest the line, so that you go on to the next one, which is the purpose of digest above: It reads the filename up to the newline, so that we go on to reading the number on the next line.

You gotta love Apple for making it so easy, when you have the tools installed! :slight_smile:

This way isn’t the most portable, but you may just fire up an editor, and make the executable, and later on, just drop it inside a script bundle and take it from there. And it is way faster to make the solution, than figure it out with bc, at least for me, I really deem this to be a to little job for awk, but it should be as fast to create as the C-version above:

#!/usr/bin/awk -f { a+=$1 } END { printf("%.2f\n",((a * 512 ) /1000000000)) }
You must make it executable with chmod +u dusum.awk, and either put it in a folder that is in your path, or specify the full path for it in the pipe where it comes right after the “du” statement.

Thanks for the heads up, I didn’t know that. I’m working mostly on 10.6.8 at the moment while I have the most fastest MBP here next to me with 10.8 which gets covered with a layer of dust :expressionless:

I’ll be over there in a month or so; I can take it off your hands and free up some desk space :slight_smile: