-
Notifications
You must be signed in to change notification settings - Fork 0
/
calc-folder-hash
executable file
·132 lines (120 loc) · 3.81 KB
/
calc-folder-hash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/bin/bash
printUsage() {
echo "calc-folder-hash -a (md5|sha1|sha224|sha256|sha384|sha512) [-pat \"*.mkv\"] ~/dir1 /dir2 …"
exit 1
}
containsElement () {
local e
for e in "${@:2}"; do [[ "$e" == "$1" ]] && return 0; done
return 1
}
if [ $# -lt 3 -o "$1" = "-h" ]; then
printUsage
fi
while [[ "$1" == -* ]]; do
# $1 starts with - => $1 is hopefully a parameter not a directory ;)
if [ "$1" = "-a" ]; then
shift
case "$1" in
md5)
readonly HASH_EXEC="$(which gmd5sum)"
readonly HASHFILE_EXT="md5"
;;
sha1)
readonly HASH_EXEC="$(which gsha1sum)"
readonly HASHFILE_EXT="sha1"
;;
sha224)
readonly HASH_EXEC="$(which gsha224sum)"
readonly HASHFILE_EXT="sha224"
;;
sha256)
readonly HASH_EXEC="$(which gsha256sum)"
readonly HASHFILE_EXT="sha256"
;;
sha384)
readonly HASH_EXEC="$(which gsha384sum)"
readonly HASHFILE_EXT="sha384"
;;
sha512)
readonly HASH_EXEC="$(which gsha512sum)"
readonly HASHFILE_EXT="sha512"
;;
*)
printUsage
;;
esac
shift
elif [ "$1" = "-pat" ]; then
shift
readonly SEARCH_PATTERN="$1"
shift
else
printUsage
fi
done
if [ -z "$HASH_EXEC" ]; then
# -a wasn't passed as argument
printUsage
fi
if [ -z "$SEARCH_PATTERN" ]; then
readonly SEARCH_PATTERN="*"
fi
readonly REGEX="([a-fA-F0-9]+)\ +(.+)"
for param in "$@"; do
filesToHash=()
if [ ! -d $param ]; then
echo "$param isn't a directory"
else
echo "Processing $param"
cd "$param"
hashFileName="$(basename "$(pwd)").$HASHFILE_EXT"
if [ -f "$hashFileName" ]; then
# make a list of files that are already in the hash file
filesInHashFile=()
while read line; do
[[ "$line" =~ $REGEX ]]
fileName="${BASH_REMATCH[2]}"
if [ ! -z "$fileName" ]; then
filesInHashFile+=("$fileName")
fi
done < "$hashFileName"
fi
# add all files that match SEARCH_PATTERN and are not in filesInHashFile to filesToHash
for file in $SEARCH_PATTERN; do
if [ "$file" != "$SEARCH_PATTERN" ]; then
if ! containsElement "$file" "${filesInHashFile[@]}"; then
filesToHash+=("$file")
fi
fi
done
# output files to hash
echo
echo "going to add ${#filesToHash[@]} file(s) to $hashFileName:"
for fileToHash in "${filesToHash[@]}"; do
echo "$fileToHash"
done
echo
# hash files
filesToHashLength=${#filesToHash[@]}
maxIndex=$(($filesToHashLength-1))
for i in $(seq 0 $maxIndex); do
fileToHash="${filesToHash[$i]}"
infoString=$(echo -n "File $((i+1))/$filesToHashLength ")
echo -n "$infoString"
echo-progress-bar $i $filesToHashLength $(( $(tput cols)-${#infoString} ))
hashOutput=$(pv -pr "$fileToHash" | "$HASH_EXEC")
[[ "$hashOutput" =~ $REGEX ]]
hashSum="${BASH_REMATCH[1]}"
echo "$hashSum $fileToHash" >> "$hashFileName"
# move cursor up 2
echo -ne "\033[2A"
done
# draw finished progress bar
infoString=$(echo -n "File $filesToHashLength/$filesToHashLength ")
echo -n "$infoString"
echo-progress-bar 1 1 $(( $(tput cols)-${#infoString} ))
echo -ne "\033[K"
fi
done
exit 0