Formatting du command output Formatting du command output shell shell

Formatting du command output


As an example, let's consider a directory with these files:

$ du -sk *12488   big.log200     big.pdf4       f12441412 output.txt160660  program.zip4       smallfile4       some.txt

To reformat du as you desire:

$ du -sk * | sort -rn | sed -E ':a; s/([[:digit:]]+)([[:digit:]]{3})/\1,\2/; ta' | awk -F'\t' '{printf "%10s %s\n",$1,substr($0,length($1)+2)}' 2,441,412 output.txt   160,660 program.zip    12,488 big.log       200 big.pdf         4 some.txt         4 smallfile         4 f1

Note: This approach will work even with file names that contain whitespace.

Shell function for convenience

Since the above is a lot to type, let's create a shell function:

$ dusk() { du -sk "$@" | sort -rn | sed -E ':a; s/([[:digit:]]+)([[:digit:]]{3})/\1,\2/; ta' | awk -F'\t' '{printf "%10s %s\n",$1,substr($0,length($1)+2)}';}

We can use the shell function as follows:

$ dusk * 2,441,412 output.txt   160,660 program.zip    12,488 big.log       200 big.pdf         4 some.txt         4 smallfile         4 f1

How it works

  • du -sk *

    This is our du command.

  • sort -rn

    This does a numerical sort in reverse order so that largest files come first.

  • sed -E ':a; s/([[:digit:]]+)([[:digit:]]{3})/\1,\2/; ta'

    This puts commas where we want them.

  • awk -F'\t' '{printf "%10s %s\n",$1,substr($0,length($1)+2)}';}

    This right-justifies the numbers.

Multiline version

For those who prefer their commands spread out over multiple lines:

du -sk * |    sort -rn |    sed -E ':a; s/([[:digit:]]+)([[:digit:]]{3})/\1,\2/; ta' |    awk -F'\t' '{printf "%10s %s\n",$1,substr($0,length($1)+2)}'

Compatibility with Mac OSX/BSD

Try this and see if it works on OSX:

$ echo 1234567890 | sed -E -e :a -e 's/([[:digit:]]+)([[:digit:]]{3})/\1,\2/' -e ta 1,234,567,890

If that works, then let's revise the complete command to be:

du -sk * | sort -rn | sed -E -e :a -e 's/([[:digit:]]+)([[:digit:]]{3})/\1,\2/' -e ta  | awk -F'\t' '{printf "%10s %s\n",$1,substr($0,length($1)+2)}'


Using sort and GNU awk you could (your output in file):

$ sort -nr file | awk '{printf "%'\''d %s\n",$1,$2}'1,722,104 popc293,292 electron-quick-start287,720 crm-cc...

If you want to right align the first field, you need to provide the printf with a width for the first field, for example:

$ sort -nr file | awk '{printf "%'\''9d %s\n",$1,$2}'1,722,104 popc  293,292 electron-quick-start  287,720 crm-cc

9 is the length of $1 with the commas which you could probably calculate with: length($1)+(length($1)-1)/3 for the longest $1which is the first, so:

$ sort -nr file |   awk 'NR==1 { len=length($1) + (length($1)-1)/3 }  { printf "%'\''" len "d %s\n",$1,$2 }'1,722,104 popc  293,292 electron-quick-start  287,720 crm-cc