sistema_progs

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

.nmv (3710B)


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