Files
q-tools/files/fastdu
2018-10-20 14:03:02 +03:00

131 lines
3.1 KiB
Bash
Executable File

#!/bin/bash
function helpexit() {
echo "Display file/folder sizes like 'du', but faster and actual byte sizes"
echo "Returns only the size as number"
echo " -h Human readable units"
echo " -s Summary mode, otherwise each argument folder calculated separate"
echo " -c Count files instead of summarizing sizes"
echo " -a Display animation while counting"
echo " -f # Format filesize to human readable. Command exits without scanning."
echo " --help This help"
exit
}
function filesize() {
# Return a human readable size from integer of bytes
# Usage: filesize 10000
[ "$1" = "0" ] && {
echo "0 B"
return 0
}
awk 'BEGIN{ x = '$1'
split("B kB MB GB TB PB EB ZB",type)
for(i=7;y < 1;i--)
y = x / (2^(10*i))
str=int(y*10)/10 " " type[i+2]
if (i==-1) { str = x " B" }
print str
}' || return $?
}
function siprefix() {
# Return a SI prefixed string from integer
[ "$1" = "0" ] && {
echo "0 "
return 0
}
awk 'BEGIN{ x = '$1'
split("_ k M G T P E Z",type)
for(i=7;y < 1;i--)
y = x / (10^(3*i))
str=int(y*10)/10 " " type[i+2]
if (i==-1) { str = x " " }
print str
}' || return $?
}
function animate() {
CHARS="|/-__-\\"
i=0
while true; do
sleep 0.2
printf "\r%s\r" ${CHARS:$i:1} >&2
i=$(( (i + 1)%${#CHARS} ))
done
}
function processfolder() {
if [[ "$COUNT" -eq 1 ]]; then
countfiles "$@"
else
displaysize "$@"
fi
}
function countfiles() {
SIZE=$( find "$@" -type f -printf %s"\n" 2>/dev/null | awk '{ sum += 1 } END { print int(sum)+0 }' )
[[ "$HUMAN" -eq 1 ]] && {
SIZE=$( siprefix "$SIZE" )
}
echo "${SIZE}"
}
function displaysize() {
SIZE=$( find "$@" -type f -printf %s"\n" 2>/dev/null | awk '{ sum += $1 } END { print int(sum)+0 }' )
[[ "$HUMAN" -eq 1 ]] && {
SIZE=$( filesize "$SIZE" )
}
echo "$SIZE"
}
# Get options
what=()
for (( i=1; i<=$#; i++ )); do
[[ "${!i}" = "-a" ]] && { ANIMATE=1; continue; }
[[ "${!i}" = "-f" ]] && { FORMAT=1; ((i++)); FORMAT_VALUE=${!i}; continue; }
[[ "${!i}" = "--help" ]] && helpexit
[[ "${!i}" = "-h" ]] && { HUMAN=1; continue; }
[[ "${!i}" = "-c" ]] && { COUNT=1; continue; }
[[ "${!i}" = "-s" ]] && { SUMMARY=1; continue; }
what+=( "${!i}" )
done
[[ -z "${what[@]}" ]] && what="."
# If formatting requested, do only that:
if [[ "$FORMAT" -eq 1 ]]; then
if [[ -z "$FORMAT_VALUE" ]]; then
echo -e "\nBytes argument missing\n\n"
helpexit
fi
filesize $FORMAT_VALUE
exit $?
fi
# If only one entry, dont print the name
[[ "${#what[@]}" -eq 1 ]] && SUMMARY=1
if [[ "$ANIMATE" -eq 1 ]]; then
animate &
fi
if [[ "$SUMMARY" -eq 1 ]]; then
# Display one line
processfolder "${what[@]}"
else
if [[ "$HUMAN" -eq 1 ]]; then
FORMAT="%8s %s\n"
else
FORMAT="%d\t%s\n"
fi
# One size for each argument
for dir in "${what[@]}"; do
printf "$FORMAT" "$( processfolder "$dir" )" "$dir"
done
fi
if [[ "$ANIMATE" -eq 1 ]]; then
kill %1
fi