awk help needed
Chris F.A. Johnson
cfaj-uVmiyxGBW52XDw4h08c5KA at public.gmane.org
Sat Jul 18 17:54:06 UTC 2009
On Sat, 18 Jul 2009, Giles Orr wrote:
> By way of introduction: I'm finally, finally trying to get a new
> edition of the Bashprompt HOWTO out there. This will probably result
> in me posting a lot of detailed and mildly weird questions to this
> list. This is the first.
>
> The intention of this script is to figure out how much space the files
> in the current directory take up. There are about a million ways to
> do this - and yes, I know that "ls -l" spits out a "total" line: I
> don't know what it's totaling, but my math has never agreed with it
> ... feel free to explain though. I decided that I'd like to do this
> as much in awk as possible since it does decimal math (unlike bash)
> and it's certainly the easiest way to do the text parsing. I've tried
> bc as well, but you have to use other utility programs to parse and
> split the input for it.
>
> #! /usr/bin/awk -f
>
> BEGIN {
> total = 0
You don't need that in awk; variables are automatically
initialized to 0 or the empty string.
> while ( ( "ls -l" | getline ) > 0 )
list=$( find . -maxdepth 1 -type f -exec stat -c %s {} +)
echo $(( ${list//$'\n'/ + } )) | awk ' ...
> total+=$5
> magnitude = 0
> while ( ( total/=1024 ) > 1 )
> magnitude++
> if ( magnitude == 0 ) scalesize = "B"
> if ( magnitude == 1 ) scalesize = "KiB"
> if ( magnitude == 2 ) scalesize = "MiB"
> if ( magnitude == 3 ) scalesize = "GiB"
> if ( magnitude == 4 ) scalesize = "TiB"
> if ( magnitude == 5 ) scalesize = "PiB"
> if ( magnitude == 6 ) scalesize = "EiB"
> if ( magnitude == 7 ) scalesize = "ZiB"
> if ( magnitude == 8 ) scalesize = "YiB"
> printf ("%.2f%s\n", (total*1024), scalesize)
> }
>
> The problem here is that I want to have the "total+=$5" line starting
> with "/^-/" so it matches only files in the ls output. But it barfs
> if I try that. I'm not quite sure what the problem is: perhaps
> because we're in the BEGIN section, but I couldn't figure out how to
> move the whole process into the body without it barfing again ... how
> can I make the getline output the input to the body? So as it stands,
> this goes wrong anywhere there are character devices, for example
> /dev/ , because field 5 isn't the file size.
>
> I know I can do this sort of thing:
>
> ls -l | awk '/^-/ {total+=$5} ; END {printf ("%.0f", total) }'
>
> But I'd like to have a fully self-contained awk script. Any suggestions?
>
>
--
Chris F.A. Johnson <http://cfaj.freeshell.org>
===================================================================
Author:
Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
--
The Toronto Linux Users Group. Meetings: http://gtalug.org/
TLUG requests: Linux topics, No HTML, wrap text below 80 columns
How to UNSUBSCRIBE: http://gtalug.org/wiki/Mailing_lists
More information about the Legacy
mailing list