feat(user/list_large_dirs.sh):Set version 1.0.0
[BK-2020-03.git] / user / list_large_dirs.sh
1 #!/usr/bin/env bash
2 # Desc: Lists directories immediately containing large amounts of data
3 # Usage: script.sh [int megabytes] [dir]
4 # Example: A directory named `vacation_photos` located somewhere in $HOME/
5 # containing more than 100MB of files (without checking subdirectories of
6 # `vacation_photos`) could be found by running:
7 # $ script.sh 100 "$HOME"
8 # /home/johndoe/Pictures/unsorted/notjunk/vacation_photos
9 # Version: 0.1.0
10
11 yell() { echo "$0: $*" >&2; } # print script path and all args to stderr
12 die() { yell "$*"; exit 111; } # same as yell() but non-zero exit status
13 must() { "$@" || die "cannot $*"; } # runs args as command, reports args if command fails
14 checkInt() {
15 # Desc: Checks if arg is integer
16 # Usage: checkInt arg
17 # Input: arg: integer
18 # Output: - return code 0 (if arg is integer)
19 # - return code 1 (if arg is not integer)
20 # Example: if ! checkInt $arg; then echo "not int"; fi;
21 # Version: 0.0.1
22 local returnState
23
24 #===Process Arg===
25 if [[ $# -ne 1 ]]; then
26 die "ERROR:Invalid number of arguments:$#";
27 fi;
28
29 RETEST1='^[0-9]+$'; # Regular Expression to test
30 if [[ ! $1 =~ $RETEST1 ]] ; then
31 returnState="false";
32 else
33 returnState="true";
34 fi;
35
36 #===Determine function return code===
37 if [ "$returnState" = "true" ]; then
38 return 0;
39 else
40 return 1;
41 fi;
42 } # Checks if arg is integer
43 check_depends() {
44 local flag_return=0;
45
46 if ! command -v du 1>/dev/random 2>&1; then flag_return=1; fi;
47
48 return "$flag_return";
49 }; # returns 1 if missing dependencies
50 size_dir_contents() {
51 # usage: size_dir_contents [path]
52 # depends: find, du
53 local bytes re;
54
55 bytes=0;
56 re="^[0-9]+$";
57
58 #yell "DEBUG:Checking dir:$1";
59 while read -r addend; do
60 #yell "DEBUG:addend:$addend";
61 if [[ $addend =~ $re ]]; then
62 bytes="$((bytes + addend))";
63 fi;
64 done < <( find "$1" -maxdepth 1 -type f -exec du -b --summarize '{}' \; | cut -f1 );
65
66 echo "$bytes" && return 0;
67 }; # return size of dir immediate contents
68 main() {
69 #size_large="100000000"; # 100 MB
70
71 #yell "DEBUG:arg1:$1"; # debug
72 #yell "DEBUG:arg2:$2"; # debug
73
74 # check dependencies
75 if ! check_depends; then die "FATAL:Missing dependencies."; fi;
76
77 # check args
78 if ! checkInt "$1"; then
79 die "FATAL:Not an int:$1";
80 else
81 size_l_mb="$1"
82 size_l_b="$(( size_l_mb * 1000000 ))";
83 fi;
84 if [[ ! -d "$2" ]]; then
85 die "FATAL:Not a dir:$2";
86 else
87 dir_in="$2";
88 fi;
89
90 # check each dir size contents
91 while IFS= read -r -d $'\0' pathdir; do
92 #yell "DEBUG:Checking:pathdir:$pathdir"; # debug
93 if [[ ! -d "$pathdir" ]]; then continue; fi;
94 dir_size="$(size_dir_contents "$pathdir";)"
95 #yell "DEBUG:dir_size:$dir_size"; # debug
96 if [[ $dir_size -gt "$size_l_b" ]]; then
97 printf "%s\n" "$pathdir"; # output
98 fi;
99 #sleep 1; # debug
100 done < <(find "$dir_in" -type d -print0);
101
102 return 0;
103 };
104
105 main "$@";