sistema_progs

Programas para customizar o meu entorno de traballo nos meus equipos persoais
Log | Files | Refs

.nmv (3723B)


      1 #!/usr/bin/env bash
      2 
      3 # Description: An almost fully POSIX compliant batch file renamer
      4 #
      5 # Note: nnn auto-detects and invokes this plugin if available
      6 #       Whitespace is used as delimiter for read.
      7 #       The plugin doesn't support filenames with leading or trailing whitespace
      8 #       To use NNN_LIST your shell must support readlink(1)
      9 #
     10 # Capabilities:
     11 #    1. Basic file rename
     12 #    2. Detects order change
     13 #    3. Can move files
     14 #    4. Can remove files
     15 #    5. Switch number pairs to swap filenames
     16 #
     17 # Shell: bash
     18 # Author: KlzXS
     19 
     20 # shellcheck disable=SC1090,SC1091
     21 . "$(dirname "$0")"/.nnn-plugin-helper
     22 
     23 EDITOR="${EDITOR:-vi}"
     24 TMPDIR="${TMPDIR:-/tmp}"
     25 NNN_INCLUDE_HIDDEN="${NNN_INCLUDE_HIDDEN:-0}"
     26 VERBOSE="${VERBOSE:-0}"
     27 RECURSIVE="${RECURSIVE:-0}"
     28 
     29 case "$NNN_TRASH" in
     30 	1)
     31 		RM_UTIL="trash-put" ;;
     32 	2)
     33 		RM_UTIL="gio trash" ;;
     34 	*)
     35 		RM_UTIL="rm -ri" ;;
     36 esac
     37 
     38 exit_status=0
     39 
     40 if nnn_use_selection "Rename"; then
     41 	# shellcheck disable=SC2154
     42 	arr=$(tr '\0' '\n' < "$selection")
     43 else
     44 	findcmd="find . ! -name ."
     45 
     46 	if [ "$RECURSIVE" -eq 0 ]; then
     47 		findcmd="$findcmd -prune"
     48 	fi
     49 
     50 	if [ "$NNN_INCLUDE_HIDDEN" -eq 0 ]; then
     51 		findcmd="$findcmd ! -name \".*\""
     52 	fi
     53 
     54 	if [ -z "$NNN_LIST" ]; then
     55 		findcmd="$findcmd -print"
     56 	else
     57 		findcmd="$findcmd -printf "'"'"$NNN_LIST/%P\n"'"'
     58 	fi
     59 
     60 	arr=$(eval "$findcmd" | sort)
     61 fi
     62 
     63 lines=$(printf "%s\n" "$arr" | wc -l)
     64 width=${#lines}
     65 
     66 dst_file=$(mktemp "$TMPDIR/.nnnXXXXXX")
     67 trap 'rm -f "$dst_file"' EXIT
     68 
     69 printf "%s" "$arr" | awk '{printf("%'"${width}"'d %s\n", NR, $0)}' > "$dst_file"
     70 
     71 items=("~")
     72 while IFS='' read -r line; do
     73 	if [ -n "$NNN_LIST" ]; then
     74 		line=$(readlink "$line" || printf "%s" "$line")
     75 	fi
     76 
     77 	items+=("$line");
     78 done < <(printf "%s\n" "$arr")
     79 
     80 $EDITOR "$dst_file"
     81 
     82 while read -r num name; do
     83 	if [ -z "$name" ]; then
     84 		if [ -z "$num" ]; then
     85 			continue
     86 		fi
     87 
     88 		printf "%s: unable to parse line, aborting\n" "$0"
     89 		exit 1
     90 	fi
     91 
     92 	# check if $num is an integer
     93 	if [ ! "$num" -eq "$num" ] 2> /dev/null; then
     94 		printf "%s: unable to parse line, aborting\n" "$0"
     95 		exit 1
     96 	fi
     97 
     98 	src=${items[$num]}
     99 
    100 	if [ -z "$src" ]; then
    101 		printf "%s: unknown item number %s\n" "$0" "$num" > /dev/stderr
    102 		continue
    103 	elif [ "$name" != "$src" ]; then
    104 		if [ -z "$name" ]; then
    105 			continue
    106 		fi
    107 
    108 		if [ ! -e "$src" ] && [ ! -L "$src" ]; then
    109 			printf "%s: %s does not exit\n" "$0" "$src" > /dev/stderr
    110 
    111 			unset "items[$num]"
    112 			continue
    113 		fi
    114 
    115 		# handle swaps
    116 		if [ -e "$name" ] || [ -L "$name" ]; then
    117 			tmp="$name~"
    118 			c=0
    119 
    120 			while [ -e "$tmp" ] || [ -L "$tmp" ]; do
    121 				c=$((c+1))
    122 				tmp="$tmp~$c"
    123 			done
    124 
    125 			if mv "$name" "$tmp"; then
    126 				if [ "$VERBOSE" -ne 0 ]; then
    127 					printf "'%s' -> '%s'\n" "$name" "$tmp"
    128 				fi
    129 			else
    130 				printf "%s: failed to rename %s to %s: %s\n" "$0" "$name" "$tmp" "$!" > /dev/stderr
    131 				exit_status=1
    132 			fi
    133 
    134 			for key in "${!items[@]}"; do
    135 				if [ "${items[$key]}" = "$name" ]; then
    136 					items[$key]="$tmp"
    137 				fi
    138 			done
    139 		fi
    140 
    141 		dir=$(dirname "$name")
    142 		if [ ! -d "$dir" ] && ! mkdir -p "$dir"; then
    143 			printf "%s: failed to create directory tree %s\n" "$0" "$dir" > /dev/stderr
    144 			exit_status=1
    145 		elif ! mv -i "$src" "$name"; then
    146 			printf "%s: failed to rename %s to %s: %s\n" "$0" "$name" "$tmp" "$!" > /dev/stderr
    147 			exit_status=1
    148 		else
    149 			if [ -d "$name" ]; then
    150 				for key in "${!items[@]}"; do
    151 					items[$key]=$(printf "%s" "${items[$key]}" | sed "s|^$src\(\$\|\/\)|$name\1|")
    152 				done
    153 
    154 				if [ "$VERBOSE" -ne 0 ]; then
    155 					printf "'%s' => '%s'\n" "$src" "$name"
    156 				fi
    157 			else
    158 				true
    159 				if [ "$VERBOSE" -ne 0 ]; then
    160 					printf "'%s' -> '%s'\n" "$src" "$name"
    161 				fi
    162 			fi
    163 		fi
    164 	fi
    165 
    166 	unset "items[$num]"
    167 done <"$dst_file"
    168 
    169 unset "items[0]"
    170 for item in "${items[@]}"; do
    171 	$RM_UTIL "$item"
    172 done
    173 
    174 exit $exit_status