sel (2858B)
1 #!/bin/sh 2 3 # Allow bulk operations on a list of selected files. 4 5 # Requires: dmenu (or similar), trash (optional), open-file (for open only) 6 7 # Usage: sel [-m menu] [command] 8 # If no command is specified, shows the list of selected files 9 # Commands: 10 # add [files...]: add files to selection 11 # addall: add all files in the current folder to selection 12 # clear: clear selection 13 # cp: copy to current dir, possbily after editing filenames 14 # edit: open selection in editor 15 # mv: move to current dir, possbily after editing filenames 16 # open: open files using open-file 17 # rm: remove selected files and clear selection 18 19 # TODO: The usage of paste(1) is a bit of a hack, and for example it does 20 # not work if filenames contain tab characters. Fix this. 21 22 # Bug (probably not fixing this, use virename): moving a file to 23 # itself gives an error and rm is not run. 24 25 file="$XDG_DATA_HOME/selectedfiles" 26 menu="" # default uses dmenu-filepicker default 27 editor=${EDITOR:-vi} 28 rm="trash rm" # replace with rm -r if you don't use trash 29 30 usage() { 31 echo "Usage: sel [-m MENU] [COMMAND]" 32 echo "If no COMMAND is specified, shows the list of selected files" 33 echo "Possible commands:" 34 echo " add [files...]: add files to selection" 35 echo " addall: add all files in the current folder to selection" 36 echo " clear: clear selection" 37 echo " cp: copy to current dir, possbily after editing filenames" 38 echo " edit: open selection in editor" 39 echo " mv: move to current dir, possbily after editing filenames" 40 echo " open: open files using open-file" 41 echo " rm: remove selected files and clear selection" 42 } 43 44 while getopts "m:" opt; do 45 case "$opt" in 46 m) 47 menu="$OPTARG" 48 ;; 49 *) 50 usage 51 exit 1 52 ;; 53 esac 54 done 55 shift $((OPTIND - 1)) 56 57 add() { 58 shift 1 59 if [ -z "$1" ]; then 60 if [ -n "$menu" ]; then 61 dmenu-filepicker -m "$menu" >> "$file" 62 else 63 dmenu-filepicker >> "$file" 64 fi 65 else 66 for i in "$@"; do realpath "$i" >> "$file"; done 67 fi 68 sort -u -o "$file" "$file" 69 } 70 71 clear() { 72 cat /dev/null > "$file" 73 } 74 75 cphere() { 76 file2=$(mktemp) 77 sed 's/^.*\///' "$file" > "$file2" 78 $editor "$file2" 79 if [ "$(wc -l "$file" | awk '{print $1}')" != \ 80 "$(wc -l "$file2" | awk '{print $1}')" ]; then 81 echo "Error reading new file names" 82 return 1 83 else 84 paste "$file" "$file2" | while read -r f; do 85 fold=$(echo "$f" | sed 's/ .*//') 86 fnew=$(echo "$f" | sed 's/.* //') 87 cp -R "$fold" ./"$fnew" || return 1 88 done 89 fi 90 } 91 92 open() { 93 while read -r f; do 94 open-file "$f" 95 done < "$file" 96 } 97 98 remove() { 99 while read -r f; do 100 $rm "$f" 101 done < "$file" 102 } 103 104 if [ -z "$1" ]; then 105 cat "$file" 106 else 107 case "$1" in 108 add) 109 add "$@" 110 ;; 111 addall) 112 add ./* 113 ;; 114 clear) 115 clear 116 ;; 117 cp) 118 cphere && clear 119 ;; 120 edit) 121 $editor "$file" 122 ;; 123 mv) 124 cphere && (remove; clear) 125 ;; 126 open) 127 open 128 ;; 129 rm) 130 remove && clear 131 ;; 132 *) 133 echo "$1: not a valid sel command" 134 ;; 135 esac 136 fi