mirror of https://github.com/tLDP/LDP
106 lines
3.8 KiB
Bash
106 lines
3.8 KiB
Bash
#!/bin/bash
|
|
# tree2.sh
|
|
|
|
# Lightly modified/reformatted by ABS Guide author.
|
|
# Included in ABS Guide with permission of script author (thanks!).
|
|
|
|
## Recursive file/dirsize checking script, by Patsie
|
|
##
|
|
## This script builds a list of files/directories and their size (du -akx)
|
|
## and processes this list to a human readable tree shape
|
|
## The 'du -akx' is only as good as the permissions the owner has.
|
|
## So preferably run as root* to get the best results, or use only on
|
|
## directories for which you have read permissions. Anything you can't
|
|
## read is not in the list.
|
|
|
|
#* ABS Guide author advises caution when running scripts as root!
|
|
|
|
|
|
########## THIS IS CONFIGURABLE ##########
|
|
|
|
TOP=5 # Top 5 biggest (sub)directories.
|
|
MAXRECURS=5 # Max 5 subdirectories/recursions deep.
|
|
E_BL=80 # Blank line already returned.
|
|
E_DIR=81 # Directory not specified.
|
|
|
|
|
|
########## DON'T CHANGE ANYTHING BELOW THIS LINE ##########
|
|
|
|
PID=$$ # Our own process ID.
|
|
SELF=`basename $0` # Our own program name.
|
|
TMP="/tmp/${SELF}.${PID}.tmp" # Temporary 'du' result.
|
|
|
|
# Convert number to dotted thousand.
|
|
function dot { echo " $*" |
|
|
sed -e :a -e 's/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/;ta' |
|
|
tail -c 12; }
|
|
|
|
# Usage: tree <recursion> <indent prefix> <min size> <directory>
|
|
function tree {
|
|
recurs="$1" # How deep nested are we?
|
|
prefix="$2" # What do we display before file/dirname?
|
|
minsize="$3" # What is the minumum file/dirsize?
|
|
dirname="$4" # Which directory are we checking?
|
|
|
|
# Get ($TOP) biggest subdirs/subfiles from TMP file.
|
|
LIST=`egrep "[[:space:]]${dirname}/[^/]*$" "$TMP" |
|
|
awk '{if($1>'$minsize') print;}' | sort -nr | head -$TOP`
|
|
[ -z "$LIST" ] && return # Empty list, then go back.
|
|
|
|
cnt=0
|
|
num=`echo "$LIST" | wc -l` # How many entries in the list.
|
|
|
|
## Main loop
|
|
echo "$LIST" | while read size name; do
|
|
((cnt+=1)) # Count entry number.
|
|
bname=`basename "$name"` # We only need a basename of the entry.
|
|
[ -d "$name" ] && bname="$bname/"
|
|
# If it's a directory, append a slash.
|
|
echo "`dot $size`$prefix +-$bname"
|
|
# Display the result.
|
|
# Call ourself recursively if it's a directory
|
|
#+ and we're not nested too deep ($MAXRECURS).
|
|
# The recursion goes up: $((recurs+1))
|
|
# The prefix gets a space if it's the last entry,
|
|
#+ or a pipe if there are more entries.
|
|
# The minimum file/dirsize becomes
|
|
#+ a tenth of his parent: $((size/10)).
|
|
# Last argument is the full directory name to check.
|
|
if [ -d "$name" -a $recurs -lt $MAXRECURS ]; then
|
|
[ $cnt -lt $num ] \
|
|
|| (tree $((recurs+1)) "$prefix " $((size/10)) "$name") \
|
|
&& (tree $((recurs+1)) "$prefix |" $((size/10)) "$name")
|
|
fi
|
|
done
|
|
|
|
[ $? -eq 0 ] && echo " $prefix"
|
|
# Every time we jump back add a 'blank' line.
|
|
return $E_BL
|
|
# We return 80 to tell we added a blank line already.
|
|
}
|
|
|
|
### ###
|
|
### main program ###
|
|
### ###
|
|
|
|
rootdir="$@"
|
|
[ -d "$rootdir" ] ||
|
|
{ echo "$SELF: Usage: $SELF <directory>" >&2; exit $E_DIR; }
|
|
# We should be called with a directory name.
|
|
|
|
echo "Building inventory list, please wait ..."
|
|
# Show "please wait" message.
|
|
du -akx "$rootdir" 1>"$TMP" 2>/dev/null
|
|
# Build a temporary list of all files/dirs and their size.
|
|
size=`tail -1 "$TMP" | awk '{print $1}'`
|
|
# What is our rootdirectory's size?
|
|
echo "`dot $size` $rootdir"
|
|
# Display rootdirectory's entry.
|
|
tree 0 "" 0 "$rootdir"
|
|
# Display the tree below our rootdirectory.
|
|
|
|
rm "$TMP" 2>/dev/null
|
|
# Clean up TMP file.
|
|
|
|
exit $?
|