Skip to content

Instantly share code, notes, and snippets.

@kwart
Created May 21, 2025 08:41
Show Gist options
  • Select an option

  • Save kwart/f6798c4bae5147439d4d2c2b34f918df to your computer and use it in GitHub Desktop.

Select an option

Save kwart/f6798c4bae5147439d4d2c2b34f918df to your computer and use it in GitHub Desktop.
Sanitize file/folder names
#!/bin/bash
# Requires: python3 and unidecode module
# Install with: sudo apt install python3-unidecode OR pip3 install unidecode
dry_run=false
to_lowercase=false
strip_parens=false
print_usage() {
echo "Usage: $0 [--dry-run] [--lowercase] [--strip-parens] <file-or-directory>"
echo
echo "Options:"
echo " --dry-run Show renames without changing anything"
echo " --lowercase Convert names to lowercase"
echo " --strip-parens Remove parentheses and their contents from names"
}
rename_item() {
local f="$1"
local dir
dir=$(dirname "$f")
local base
base=$(basename "$f")
# Safe ASCII transliteration via Python
local ascii_base
ascii_base=$(python3 -c "import sys; from unidecode import unidecode; print(unidecode(sys.argv[1]))" "$base")
# Optional lowercase
if $to_lowercase; then
ascii_base=$(echo "$ascii_base" | tr '[:upper:]' '[:lower:]')
fi
# Optional parentheses stripping
if $strip_parens; then
ascii_base=$(echo "$ascii_base" | sed -E 's/ *\([^)]*\)//g' | sed -E 's/ +/ /g' | sed -E 's/^ *| *$//g')
fi
if [[ "$base" != "$ascii_base" ]]; then
local new_path="$dir/$ascii_base"
echo "Renaming: $f -> $new_path"
if ! $dry_run; then
mv -n "$f" "$new_path"
fi
fi
}
rename_to_ascii() {
local path="$1"
local items=()
if [ -d "$path" ]; then
# Collect paths first
while IFS= read -r f; do
items+=("$f")
done < <(find "$path" -depth)
# Rename in the order returned by `find -depth`
for item in "${items[@]}"; do
rename_item "$item"
done
elif [ -f "$path" ]; then
rename_item "$path"
else
echo "Error: '$path' is not a valid file or directory"
exit 1
fi
}
# --- Parse flags ---
while [[ "$1" == --* ]]; do
case "$1" in
--dry-run) dry_run=true ;;
--lowercase) to_lowercase=true ;;
--strip-parens) strip_parens=true ;;
--help) print_usage; exit 0 ;;
*) echo "Unknown option: $1"; print_usage; exit 1 ;;
esac
shift
done
# --- Path argument required ---
if [ -z "$1" ]; then
print_usage
exit 1
fi
rename_to_ascii "$1"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment