dots

Personal dotfiles
git clone git://git.gormless.xyz/dots.git
Log | Files | Refs

rename (1571B)


      1 #!/bin/sh
      2 
      3 set -f -e -u
      4 
      5 EDITOR="${EDITOR:-${VISUAL:-vi}}"
      6 
      7 usage()
      8 {
      9 	echo "usage: rename [file...]" >&2
     10 	exit 1
     11 }
     12 
     13 # quote and escape filename for moving
     14 quote()
     15 {
     16 	echo "$1" | sed "s/'/'\\\\''/g; s/^/'/; s/\$/'/"
     17 }
     18 
     19 # populate the files $old and $new with filenames, one per line
     20 populatefiles()
     21 {
     22 	if [ $# -eq 0 ]
     23 	then                            # run on stdin
     24 		cat | tee "$old" > "$new"
     25 	else                            # run on arguments
     26 		for i
     27 		do
     28 			printf "%s\n" "$i" >> "$old"
     29 			printf "%s\n" "$i" >> "$new"
     30 		done
     31 	fi
     32 }
     33 
     34 # edit the filenames in $new and test if they are valid
     35 editfile()
     36 {
     37 	if [ "$(wc -l <"$old")" -ne "$(sort -u "$old" | wc -l)" ]
     38 	then
     39 		echo "rename: repeated filenames to be renamed" >&2
     40 		exit 1
     41 	fi
     42 
     43 	"$EDITOR" "$new" </dev/tty
     44 
     45 	if [ $(wc -l <"$new") -ne $(wc -l <"$old") ]
     46 	then
     47 		echo "rename: number of filenames not equal to number of files" >&2
     48 		exit 1
     49 	fi
     50 
     51 	if [ "$(wc -l <"$new")" -ne "$(sort -u "$new" | wc -l)" ]
     52 	then
     53 		echo "rename: repeated target filenames" >&2
     54 		exit 1
     55 	fi
     56 }
     57 
     58 # create $cmd file
     59 createcmd()
     60 {
     61 	cat /dev/null >"$cmd"
     62 	while read -r from <&3 && read -r to <&4
     63 	do
     64 		if [ "$from" != "$to" ]
     65 		then
     66 			from=$(quote "$from")
     67 			to=$(quote "$to")
     68 			printf "mv %s\t%s\n" "$from" "$to" >> "$cmd"
     69 		fi
     70 	done 3<"$old" 4<"$new"
     71 }
     72 
     73 # remove temporary files
     74 cleanup()
     75 {
     76 	rm -f "$old" "$new" "$cmd"
     77 }
     78 
     79 while getopts 'h' c
     80 do
     81 	case "$c" in
     82 	h|*)
     83 		usage
     84 		;;
     85 	esac
     86 done
     87 shift $((OPTIND -1))
     88 
     89 old=$(mktemp)
     90 new=$(mktemp)
     91 cmd=$(mktemp)
     92 
     93 trap cleanup EXIT
     94 
     95 populatefiles "$@"
     96 editfile
     97 createcmd
     98 sh -x "$cmd"
     99 
    100 exit 0