File: filesizes.sh 1 #!/bin/sh 2 3 # The MIT License (MIT) 4 # 5 # Copyright (c) 2026 pacman64 6 # 7 # Permission is hereby granted, free of charge, to any person obtaining a copy 8 # of this software and associated documentation files (the "Software"), to deal 9 # in the Software without restriction, including without limitation the rights 10 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 # copies of the Software, and to permit persons to whom the Software is 12 # furnished to do so, subject to the following conditions: 13 # 14 # The above copyright notice and this permission notice shall be included in 15 # all copies or substantial portions of the Software. 16 # 17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 # SOFTWARE. 24 25 26 # filesizes [options...] [files/folders...] 27 # 28 # Show all filesizes as TSV lines, after a header/column line. Besides sizes 29 # in bytes, the size in 1024-byte kilobytes is also shown, rounded up. By 30 # default the block-size used to round up is 4, which amounts to 4096-byte 31 # blocks. 32 # 33 # You can change the block-size round-up via the likes of `-4k`, `-8k`, and 34 # so on, without the quotes. Also, you can give this tool a mix of files and 35 # folders, allowing you to run it with expanding file-patterns on the shell. 36 # 37 # The options are, available both in single and double-dash versions 38 # 39 # -4k, -8k, -16k, ... custom block-size round-up 40 # -h, -help show this help message 41 # -s, -sort, -sorted reverse-sort by filesize 42 # -t, -top limit search to top-level files, in folders given 43 44 45 case "$1" in 46 -h|--h|-help|--help) 47 awk '/^# +filesizes /, /^$/ { gsub(/^# ?/, ""); print }' "$0" 48 exit 0 49 ;; 50 esac 51 52 sorted=0 53 max_depth='' 54 block_size=4 55 56 for arg in "$@"; do 57 if [ "${arg}" = '--' ]; then 58 shift 59 break 60 fi 61 62 case "${arg}" in 63 -s|--s|-sort|--sort|-sorted|--sorted) 64 sorted=1 65 shift 66 continue 67 ;; 68 69 -t|--t|-top|--top) 70 max_depth='-maxdepth 1' 71 shift 72 continue 73 ;; 74 esac 75 76 if echo "${arg}" | grep -E -q '^--?[0-9][kK]+$'; then 77 block_size="$(echo "${arg}" | sed 's-[^0-9]--g')" 78 shift 79 continue 80 fi 81 82 break 83 done 84 85 if [ $# -eq 0 ]; then 86 awk '/^# +filesizes /, /^$/ { gsub(/^# ?/, ""); print }' "$0" 87 exit 0 88 fi 89 90 [ "$1" = '--' ] && shift 91 92 printf "file\tbytes\tblocks\n" 93 94 for arg in "${@:-.}"; do 95 if [ -f "${arg}" ]; then 96 wc -c "${arg}" 97 continue 98 fi 99 100 if [ -d "${arg}" ]; then 101 find "${arg}" ${max_depth} -type f -exec wc --total=never -c {} + 102 fi 103 done | awk ' 104 { 105 gsub(/^ *| *\r$/, "") 106 gsub(/^([^ ])*/, "&\t") 107 gsub(/ *\t */, "\t") 108 print 109 } 110 ' | awk -F "\t" -v OFS="\t" -v block="${block_size}" ' 111 { 112 f = $1 / (block * 1024) 113 n = f - f % 1 114 if (f % 1) n++ 115 print $2, $1, n * block 116 } 117 ' | if [ "${sorted}" -eq 1 ]; then 118 sort -t "$(printf '\t')" -rnk2,2 -k1,1 119 else 120 cat 121 fi