Shell script to calculate the total space consumed by a user by file-size
AWK="/bin/awk"



It's easier and more readable if you just set your PATH to something appropriate.


USERS="`"$AWK" '$7 &gt;= "2002" &amp;&amp; $7 &lt;= "2018"' $FILE | "$AWK" '{print $3}' | sort -u`"



Backticks should almost always be replaced by $( … ), which is faster because it does not invoke a subshell.  

Literal numbers should not be quoted.  It happens to still do what you want in awk; in some languages it won't.  A bad habit, easily avoided.

There's no need to invoke awk a second time to extract the third field.  Simply pair the action {print $3} with the condition ($7 &gt;= …) that's already there.

It's good form to indent the body of a for block (or any other block).


echo "User $user " | tr -d "\n";



To suppress a newline on echo, use echo -n.


column -t



This has some awkward consequences, like tabs inside of labels ("TotalTABSpace") and unaligned numbers.  printf will give much prettier results.  Both bash and awk provide it.


total/1024/1024/1024 



Nothing wrong with this, as such, but 2**30 is useful shorthand for gigabyte. 


==============================================================



Bash can generate sequences like this with the idiom printf "=%.0s" {1..62}.  The = is the character and 62 is the count.

You're traversing the file three times and extracting the same information each time.  This is going to get slow as the file grows.  Awk has associative arrays: you can store a subtotal for each user, then iterate and print those subtotals at the end of the awk script, accomplishing the whole thing in one go.

Putting it all together:

/bin/awk -vusrfmt="User %-20s Total Space consumed: %11.6f GB\n" \
         -vsumfmt=$( printf "=%.0s" {1..62} )"\nTotal Space consumed by All Users: %.6f GB\n"  '
  $7 &gt;= 2002 &amp;&amp; $7 &lt;= 2018 { 
    subtot[$3]+=$4
    tot+=$4
  }
  END {
    for (u in subtot) printf usrfmt, u, subtot[u] / 2**30
    printf sumfmt, tot / 2**30
  }'