Skip to content

Selective file sync

Shell
Text
1 day ago

Scripts for finding files by name, building transfer lists and syncing matched files to another system.

bash
files
rsync
shell
utils
send_movies.sh
#!/usr/bin/env bash
set -Eeuo pipefail
START_DIR="/path/to/your/directory"
FILENAME_LIST="./movies.txt"
DESTINATION="{{HOSTNAME_VAR}}:~/incoming/movies/"
ERROR_LOG="./error.log"
: > "$ERROR_LOG"
log_error() {
echo "[$(date '+%F %T')] $*" >> "$ERROR_LOG"
}
trap 'log_error "Script failed on line $LINENO with exit code $?"' ERR
[[ -d "$START_DIR" ]] || {
log_error "START_DIR does not exist: $START_DIR"
exit 1
}
[[ -f "$FILENAME_LIST" ]] || {
log_error "FILENAME_LIST does not exist: $FILENAME_LIST"
exit 1
}
declare -a movie_paths=()
while IFS= read -r filename || [[ -n "$filename" ]]; do
[[ -z "$filename" ]] && continue
[[ "${filename:0:1}" == "#" ]] && continue
matches=()
while IFS= read -r path; do
matches+=("$path")
done < <(
find "$START_DIR" -type f \
\( -iname "${filename}.mp4" -o -iname "${filename}.mkv" \) \
-exec realpath {} \; \
2>>"$ERROR_LOG"
)
if [[ ${#matches[@]} -eq 0 ]]; then
log_error "No matches found for: $filename"
continue
fi
movie_paths+=("${matches[@]}")
done < "$FILENAME_LIST"
mapfile -t movie_paths < <(
printf '%s\n' "${movie_paths[@]}" | sort -u
)
if [[ ${#movie_paths[@]} -eq 0 ]]; then
log_error "No files matched any entries."
exit 1
fi
echo "Found ${#movie_paths[@]} files."
echo "Files to transfer:"
printf ' %s\n' "${movie_paths[@]}"
for src in "${movie_paths[@]}"; do
filename=$(basename "$src")
movie_dir="${filename%.*}"
echo "Copying:"
echo " $src"
echo " -> ${DESTINATION}${movie_dir}/"
rsync -avh --progress \
"$src" \
"${DESTINATION}${movie_dir}/" \
2>>"$ERROR_LOG"
done