sistema_progs

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

.nmv (3835B)


      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 EDITOR="${EDITOR:-vi}"
     21 TMPDIR="${TMPDIR:-/tmp}"
     22 NNN_INCLUDE_HIDDEN="${NNN_INCLUDE_HIDDEN:-0}"
     23 VERBOSE="${VERBOSE:-0}"
     24 RECURSIVE="${RECURSIVE:-0}"
     25 
     26 case "$NNN_TRASH" in
     27 	1)
     28 		RM_UTIL="trash-put" ;;
     29 	2)
     30 		RM_UTIL="gio trash" ;;
     31 	*)
     32 		RM_UTIL="rm -ri" ;;
     33 esac
     34 
     35 selection=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
     36 exit_status=0
     37 
     38 dst_file=$(mktemp "$TMPDIR/.nnnXXXXXX")
     39 
     40 if [ -s "$selection" ]; then
     41 	printf "Rename 'c'urrent / 's'election? "
     42 	read -r resp
     43 
     44     if ! [ "$resp" = "c" ] && ! [ "$resp" = "s" ]; then
     45         exit 1
     46     fi
     47 fi
     48 
     49 if [ "$resp" = "s" ]; then
     50 	arr=$(tr '\0' '\n' < "$selection")
     51 else
     52 	findcmd="find . ! -name ."
     53 
     54 	if [ "$RECURSIVE" -eq 0 ]; then
     55 		findcmd="$findcmd -prune"
     56 	fi
     57 
     58 	if [ "$NNN_INCLUDE_HIDDEN" -eq 0 ]; then
     59 		findcmd="$findcmd ! -name \".*\""
     60 	fi
     61 
     62 	if [ -z "$NNN_LIST" ]; then
     63 		findcmd="$findcmd -print"
     64 	else
     65 		findcmd="$findcmd -printf "'"'"$NNN_LIST/%P\n"'"'
     66 	fi
     67 
     68 	arr=$(eval "$findcmd" | sort)
     69 fi
     70 
     71 lines=$(printf "%s\n" "$arr" | wc -l)
     72 width=${#lines}
     73 
     74 printf "%s" "$arr" | awk '{printf("%'"${width}"'d %s\n", NR, $0)}' > "$dst_file"
     75 
     76 items=("~")
     77 while IFS='' read -r line; do
     78 	if [ -n "$NNN_LIST" ]; then
     79 		line=$(readlink "$line" || printf "%s" "$line")
     80 	fi
     81 
     82 	items+=("$line");
     83 done < <(printf "%s\n" "$arr")
     84 
     85 $EDITOR "$dst_file"
     86 
     87 while read -r num name; do
     88 	if [ -z "$name" ]; then
     89 		if [ -z "$num" ]; then
     90 			continue
     91 		fi
     92 
     93 		printf "%s: unable to parse line, aborting\n" "$0"
     94 		exit 1
     95 	fi
     96 
     97 	# check if $num is an integer
     98 	if [ ! "$num" -eq "$num" ] 2> /dev/null; then
     99 		printf "%s: unable to parse line, aborting\n" "$0"
    100 		exit 1
    101 	fi
    102 
    103 	src=${items[$num]}
    104 
    105 	if [ -z "$src" ]; then
    106 		printf "%s: unknown item number %s\n" "$0" "$num" > /dev/stderr
    107 		continue
    108 	elif [ "$name" != "$src" ]; then
    109 		if [ -z "$name" ]; then
    110 			continue
    111 		fi
    112 
    113 		if [ ! -e "$src" ] && [ ! -L "$src" ]; then
    114 			printf "%s: %s does not exit\n" "$0" "$src" > /dev/stderr
    115 
    116 			unset "items[$num]"
    117 			continue
    118 		fi
    119 
    120 		# handle swaps
    121 		if [ -e "$name" ] || [ -L "$name" ]; then
    122 			tmp="$name~"
    123 			c=0
    124 
    125 			while [ -e "$tmp" ] || [ -L "$tmp" ]; do
    126 				c=$((c+1))
    127 				tmp="$tmp~$c"
    128 			done
    129 
    130 			if mv "$name" "$tmp"; then
    131 				if [ "$VERBOSE" -ne 0 ]; then
    132 					printf "'%s' -> '%s'\n" "$name" "$tmp"
    133 				fi
    134 			else
    135 				printf "%s: failed to rename %s to %s: %s\n" "$0" "$name" "$tmp" "$!" > /dev/stderr
    136 				exit_status=1
    137 			fi
    138 
    139 			for key in "${!items[@]}"; do
    140 				if [ "${items[$key]}" = "$name" ]; then
    141 					items[$key]="$tmp"
    142 				fi
    143 			done
    144 		fi
    145 
    146 		dir=$(dirname "$name")
    147 		if [ ! -d "$dir" ] && ! mkdir -p "$dir"; then
    148 			printf "%s: failed to create directory tree %s\n" "$0" "$dir" > /dev/stderr
    149 			exit_status=1
    150 		elif ! mv -i "$src" "$name"; then
    151 			printf "%s: failed to rename %s to %s: %s\n" "$0" "$name" "$tmp" "$!" > /dev/stderr
    152 			exit_status=1
    153 		else
    154 			if [ -d "$name" ]; then
    155 				for key in "${!items[@]}"; do
    156 					items[$key]=$(printf "%s" "${items[$key]}" | sed "s|^$src\(\$\|\/\)|$name\1|")
    157 				done
    158 
    159 				if [ "$VERBOSE" -ne 0 ]; then
    160 					printf "'%s' => '%s'\n" "$src" "$name"
    161 				fi
    162 			else
    163 				true
    164 				if [ "$VERBOSE" -ne 0 ]; then
    165 					printf "'%s' -> '%s'\n" "$src" "$name"
    166 				fi
    167 			fi
    168 		fi
    169 	fi
    170 
    171 	unset "items[$num]"
    172 done <"$dst_file"
    173 
    174 unset "items[0]"
    175 for item in "${items[@]}"; do
    176 	$RM_UTIL "$item"
    177 done
    178 
    179 rm "$dst_file"
    180 exit $exit_status