Skip to content

Instantly share code, notes, and snippets.

@bbpennel
Last active September 24, 2019 13:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bbpennel/3375cc5d6fb4d555a8910b54a2745546 to your computer and use it in GitHub Desktop.
Save bbpennel/3375cc5d6fb4d555a8910b54a2745546 to your computer and use it in GitHub Desktop.
Bash script which replaces all non-ASCII characters with another character in filenames for all files and directories contained within the target directory.
#!/usr/bin/env bash
USAGE="$(basename "$0") [-h] [-d] [-e] target_dir
Replaces all non-ASCII characters with another character in filenames
for all files and directories contained within the target directory.
where:
-h, --help Show this help text
-d, --dry-run Display the expected changes, but do not perform them. If
a file is in a directory that needs to be renamed, it will
be reported during a dry run.
-e, --replace-with Text which will replace non-ASCII characters. Default '_'.
"
REPLACE_WITH="_"
TARGET_DIR=""
while (( "$#" )); do
case "$1" in
-e|--replace-with)
REPLACE_WITH=$2
shift 2
;;
-d|--dry-run)
DRY_RUN=YES
shift
;;
-h|--help)
SHOW_HELP=YES
shift
;;
-*|--*=) # unsupported flags
echo "Error: Unsupported flag $1" >&2
exit 1
;;
*) # preserve positional arguments
TARGET_DIR="$TARGET_DIR $1"
shift
;;
esac
done
set -- "$TARGET_DIR" # restore positional parameters
if [ "$SHOW_HELP" = "YES" ] || [ "$TARGET_DIR" = "" ]; then
echo "$USAGE"
exit 0
fi
if [ "$DRY_RUN" != "YES" ]; then
echo "Replacing non-ASCII characters with '$REPLACE_WITH'"
RENAME_CMD=' rename($_, $new);'
else
echo "WARNING: Performing dry run, no file names will be changed"
fi
echo "-----------------"
do_replace() {
FIND_TYPE=$1
find $TARGET_DIR -type $FIND_TYPE -print0 | \
perl -n0e '
use open qw/:std :utf8/;
$new = $_;
if ($new =~ s/([\x{0001}-\x{001F}\x{E000}-\x{F8FF}\*"\\\|:\?<>])+/'"$REPLACE_WITH"'/g && $_ ne $new) {
# trim off the null character
$new = substr($new, 0, -1);
# Trim whitespace
$new =~ s/^\s+|\s+$//g ;
print("Renaming \"$_\" to \"$new\"\n");
if (-e $new) {
print("** WARNING: Skipped rename, file already exists with new name\n");
} else {
'"$RENAME_CMD"'
}
}'
}
do_replace 'd'
do_replace 'f'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment