ambevar-dotfiles/.scripts/dataindex

72 lines
1.6 KiB
Bash
Executable File

#!/bin/sh
_usage () {
cat<<EOF
Usage: ${1##*/} [OPTIONS] FOLDERS
Output index of folder hierarchies to stdout. This is used as a small "backup"
purpose. In case of data loss, it is still possible to get the full file list
thanks to the indexes.
Options:
-f: When outputting to a file, overwrite if it exists.
-w: Output each index to individual files in current folder. It uses the folder
name as basename.
EOF
}
opt_noclobber=true
opt_file=false
while getopts ":fhw" opt; do
case $opt in
f)
opt_noclobber=false ;;
h)
_usage "$0"
exit 0 ;;
w)
opt_file=true ;;
\?)
_usage "$0"
exit 1 ;;
esac
done
shift $(($OPTIND - 1))
if [ $# -eq 0 ]; then
_usage "$0"
exit 1
fi
## 'realpath' is required in case argument is ending with '.' or '..'.
if ! command -v realpath >/dev/null 2>&1; then
echo "'realpath' not found in PATH. Exiting." >&2
exit 1
fi
for i ; do
## Find over '.*' and '*', is bad practice since if will fail on
## non-existing files or for files beginning with a dash. The 'printf'
## command in find is for GNU find only.
## The two following lines do the same for the same time cost. The former is shorter.
# find "$i" -type f | awk -v str="$i" '{l=length(str)+2; print substr($0, l)}' | sort > "$OUTPUT"
## 'LC_ALL=C sort' is required to make sure to output is consistent across
## different systems.
(cd -- "$i" && find . -type f) | sed 's/^.\///' | LC_ALL=C sort | \
if $opt_file; then
i="$(realpath -- "$i")"
base="${i##*/}"
[ ! -d "$i" ] && continue
output="$base.index"
[ -e "$OUTPUT" ] && $opt_noclobber && output="$base-$(date +%F-%T).index"
echo "$output"
cat > "$output"
else
cat
fi
done