2 # Desc: Rename files to remove common prefix
3 # Usage: triml.sh [FILE] ([FILE]…)
4 # Example: triml.sh ./*.txt
7 yell
() { echo "$0: $*" >&2; } # print script path and all args to stderr
8 die
() { yell
"$*"; exit 111; } # same as yell() but non-zero exit status
9 must
() { "$@" || die
"cannot $*"; } # runs args as command, reports args if command fails
11 # Desc: Iteratively identify common prefix
12 # Input: "$@" arguments
14 local prefix
="$1"; # start with first arg
15 shift; # don't compare first to first
17 while [[ "$arg" != "$prefix"* ]]; do
18 prefix
="${prefix%?}"; # trim end of prefix if match
21 printf "%s" "$prefix";
22 }; # Get common prefix of arguments
24 # Desc: Display script usage information
29 # Depends: GNU-coreutils 8.30 (cat)
41 } # Display information on how to use this script.
43 # Desc: Prompt user to go approve/disapprove or list files to be moved.
45 read -rp "Rename ${#args[@]} files? (y/N or l/list): " choice
;
48 yell
"STATUS:Renaming...";
52 for i
in "${!args[@]}"; do
53 yell
"Rename: ${args[i]} -> ${args_defront[i]}";
57 die
"FATAL:Operation aborted.";
60 yell
"Invalid option.";
63 }; # prompt user to continue operation
65 declare -a args args_defront
;
67 declare path_dir name_file name_file_new
;
69 # Check if no arguments are passed
70 if [[ "$#" -le 0 ]]; then
71 ## Act on working dir files
72 mapfile
-t args
< <(find .
-mindepth 1 -maxdepth 1 -type f
);
74 ## Act on argument-specified file paths
78 # Check that all args are file paths
79 for arg
in "${args[@]}"; do
80 if [[ ! -f "$arg" ]]; then
82 die
"FATAL:Not a file:${arg}"; fi;
85 # Get common prefix of all file basenames
86 ## Assemble directory paths and file name arrays
87 for i
in "${!args[@]}"; do
88 #args_path[i]="$(dirname "${args[i]}")";
89 args_file
[i
]="$(basename "${args[i]}")";
91 prefix
="$(get_prefix "${args_file[@]}")";
92 #declare -p args prefix; # debug
93 if [[ "${#prefix}" -le 0 ]]; then
94 #declare -p prefix; # debug
95 die
"FATAL:No file prefix found."; fi;
97 # Assemble paths with defronted basenames
98 for i
in "${!args[@]}"; do
99 path_dir
="$(dirname "${args[i]}")";
100 name_file
="$(basename "${args[i]}")";
101 name_file_new
="${name_file#"${prefix}"}";
102 args_defront
[i
]="${path_dir}/${name_file_new}";
105 # Throw rename warning
106 must prompt_continue
;
108 # Rename files to defront prefix
109 for i
in "${!args[@]}"; do
110 if mv -n "${args[i]}" "${args_defront[i]}"; then
111 yell
"STATUS:Moved ${args[i]} to ${args_defront[i]}";
113 die
"FATAL:Failed to move ${args[i]} to ${args_defront[i]}";
119 # Author: Steven Baltakatei Sandoval