CGM : It's an invariable rule that however many megabytes/gigabytes/terabytes of disk space you have, eventually they will fill up. When that happens the next step is usually a frantic rush to see what old data can be deleted or compressed to make space for new stuff. This script is designed to help with that process.
It basically just runs the Unix command du ("Disk Usage") and presents the output as a graphical tree, sorted so that the biggest directories/files are at the top. Once you have identified the files you want to delete/compress/etc., you can select them in the tree and copy/paste the pathnames to a shell.
Notes:
#!/usr/local/bin/tcl # diskusage - display disk space used in tree gui # C. Macleod 24/12/10 - 6/9/20 if {[catch {package require Tk}]} { puts stderr "This program needs an X-window display." exit } ########################### Set up screen ############################ package require treectrl package require tooltip treectrl .tc -yscrollcommand {.ys set} -xscrollcommand {.xs set} -width 600 -height 400 .tc column create -text {Size kB} .tc column create -text {Mod Date} .tc column create -text {File Name} .tc element create el1 text .tc style create s1 .tc style elements s1 el1 .tc style layout s1 el1 -ipadx 2 .tc element configure el1 -fill {red active green selected} .tc configure -treecolumn 0 -selectmode extended tooltip::tooltip .tc {Select files/directories with keyboard or mouse. Control-C copies selected pathname(s). Right-click to copy Item/Pathnames/Details.} scrollbar .ys -command {.tc yview} -orient vertical scrollbar .xs -command {.tc xview} -orient horizontal grid .tc .ys grid .tc -sticky nsew grid .ys -sticky ns grid .xs -sticky ew grid columnconfigure . 0 -weight 1 grid columnconfigure . 1 -weight 0 grid rowconfigure . 0 -weight 1 grid rowconfigure . 1 -weight 0 ##################### Get and display sizes under specified path ###################### proc read_sizes ppath { set ::parent root set ::old_depth [llength [file split $ppath]] set cmd "| du -a -k --time --threshold=$::min_size" lappend cmd $ppath set du [open $cmd] fileevent $du readable [list read_item $du] } proc read_item du { global parent old_depth if {[gets $du line] == -1} { catch {close $du} incr ::done return } if {! [regexp -- {(\d+)\s+([\d\-]+\s[\d:]+)\s+(.*)} $line - size mtime path]} continue set depth [llength [file split $path]] for {set x $old_depth} {$x <= $depth} {incr x} { set isdir [expr {$x < $depth}] set isopen [expr {[.tc depth $parent] < 1}] set item [.tc item create -parent $parent -button $isdir -open $isopen] .tc item style set $item 0 s1 1 s1 2 s1 if {$isdir} { set parent $item .tc item text $item 0 0 set dpath $path for {set y $x} {$y < $depth} {incr y} { set dpath [file dir $dpath] } .tc item text $item 2 $dpath } } if {$depth < $old_depth} { set item $parent set parent [.tc item parent $item] } .tc item text $item 1 $mtime .tc item text $item 2 $path .tc item text $item 0 $size set old_depth $depth if {[.tc item isopen $parent]} { .tc item sort $parent -integer -decreasing } maybe_update } #################### Expand directory ##################### .tc notify bind .tc <Expand-after> { expand %I } proc expand item { .tc item sort $item -integer -decreasing } ############# Update display but not more than once per 2 sec ############## set next_update_time [clock seconds] proc maybe_update {} { set now [clock seconds] if {$now >= $::next_update_time} { set ::next_update_time [expr {$now + 2}] update } } #################### Copy on right click or ctrl-C ##################### set my_selection {} proc my_copy text { set ::my_selection $text selection own . } selection handle . onSelect proc onSelect {offset maxChars} { return [string range $::my_selection $offset [expr {$offset+$maxChars}]] } menu .rmenu -tearoff 0 bind .tc <3> "right_click %x %y %X %Y" bind .tc <Control-a> {.tc selection add first last} bind .tc <Control-c> copy_pathnames proc right_click {x y X Y} { .tc identify -array ident $x $y if {$ident(where) eq "item"} { set text [.tc item text $ident(item) $ident(column)] } else { set text {} } .rmenu delete 0 end .rmenu add command -label "Copy item '$text'" -command [list my_copy $text] .rmenu add command -label "Copy selected pathnames" -accelerator ^C -command copy_pathnames .rmenu add command -label "Copy selected size/date/pathnames" -command copy_details tk_popup .rmenu $X $Y } proc selected_pathnames {} { set text {} foreach item [.tc selection get 0 end] { lappend text [.tc item text $item 2] } return $text } proc copy_pathnames {} {my_copy [selected_pathnames]} proc copy_details {} { set text {} foreach item [.tc selection get 0 end] { append text "[join [.tc item text $item] \t]\n" } my_copy $text } ########################### Start things up ############################ set min_size 100K if {[llength $argv]} { set filelist $argv } else { set filelist . } wm title . "Disk Usage: [pwd] $filelist" . configure -cursor watch focus .tc update foreach f $filelist { read_sizes $f vwait done } . config -cursor {}
See also : Tktreemap