#!/usr/bin/env bash set -euo pipefail MODE="${1:-}" ROOT="${2:-}" if [[ -z "$MODE" || -z "$ROOT" ]]; then echo "Usage: $0 " exit 1 fi cd "$ROOT" ENC_SEP="__" # Separator for encoding encode() { find . -type f | while read -r file; do # Skip files already in root if [[ "$file" == "./"*"/"* ]]; then relpath="${file#./}" # remove leading "./" dir=$(dirname "$relpath") base=$(basename "$relpath") # Encode: replace slashes with "__" encoded="${dir//$'/'/$ENC_SEP}__$base" # Avoid collision if [[ -e "$encoded" ]]; then i=1 while [[ -e "${encoded%.*}_$i.${encoded##*.}" ]]; do i=$((i+1)) done encoded="${encoded%.*}_$i.${encoded##*.}" fi mv "$relpath" "$encoded" fi done # Remove empty dirs find . -type d -empty -delete } decode() { find . -maxdepth 1 -type f | while read -r f; do filename=$(basename "$f") # Split encoded name: dirparts__file.ext parts=(${filename//$ENC_SEP/ }) # Last part is the real filename realfile="${parts[-1]}" unset 'parts[-1]' # Rebuild directory path dir=$(printf "/%s" "${parts[@]}") dir="${dir#/}" # Remove leading slash if [[ -n "$dir" ]]; then mkdir -p "$dir" mv "$f" "$dir/$realfile" fi done } case "$MODE" in encode) encode ;; decode) decode ;; *) echo "Unknown mode: $MODE"; exit 1 ;; esac