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