#!/usr/bin/env bash # Description: Clean filename or dirname (either hovered or selections) # to be more shell-friendly. This script cleans # non A-Za-z0-9._- characters. # and replaces it with underscore (_). # # It supports cleaning single/double quote, newline, # leading, trailing spaces. # # eg. # to be continued (つづく).mp4 -> to_be_continued______.mp4 # [work] stuff.txt -> _work__stuff.txt # home's server -> home_s_server # qwe\trty -> __qwe_rty # # And if there are two almost similar filenames # like: 'asd]f' and 'asd f' both will be renamed to 'asd_f', # to avoid overwriting, the last file will be prepended by _. # So they will be: 'asd_f' and '_asd_f' # # Dependencies: sed # # Shell: Bash # Author: Benawi Adha prompt=true sel=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection} cleanup() { # printf "%s" "$1" | sed -e 's/[^A-Za-z0-9._-]/_/g' printf "%s" "$1" | sed 's/[^A-Za-z0-9._-]/_/g' | sed ':a;N;$!ba;s/\n/_/g' } if [ -s "$sel" ]; then targets=() while IFS= read -r -d '' i || [ -n "$i" ]; do targets+=( "$(basename "$i")" ) done < "$sel" else targets=("$1") fi for i in "${targets[@]}"; do printf "%s -> %s\n" "$i" "$(cleanup "$i")"; done if $prompt; then echo printf "Proceed [Yn]? " read -r input case "$input" in y|Y|'') ;; *) echo "Canceled" exit ;; esac fi for i in "${targets[@]}"; do if [ "$i" != "$(cleanup "$i")" ]; then tmp='' if [ -e "$(cleanup "$i")" ]; then tmp='_' fi mv -- "$i" "$tmp$(cleanup "$i")"; fi done # Clear selection if [ -s "$sel" ] && [ -p "$NNN_PIPE" ]; then printf "-" > "$NNN_PIPE" fi