#!/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