feat(user/ffmpeg_parallel_encode.sh):Add parallel | ffmpeg script
[BK-2020-03.git] / user / triml.sh
1 #!/usr/bin/env bash
2 # Desc: Rename files to remove common prefix
3 # Usage: triml.sh [FILE] ([FILE]…)
4 # Example: triml.sh ./*.txt
5 # Version: 0.0.1
6
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
10 get_prefix() {
11 # Desc: Iteratively identify common prefix
12 # Input: "$@" arguments
13 # Output: stdout
14 local prefix="$1"; # start with first arg
15 shift; # don't compare first to first
16 for arg in "$@"; do
17 while [[ "$arg" != "$prefix"* ]]; do
18 prefix="${prefix%?}"; # trim end of prefix if match
19 done;
20 done;
21 printf "%s" "$prefix";
22 }; # Get common prefix of arguments
23 show_usage() {
24 # Desc: Display script usage information
25 # Usage: show_usage
26 # Version 0.0.2
27 # Input: none
28 # Output: stdout
29 # Depends: GNU-coreutils 8.30 (cat)
30 cat <<'EOF'
31 USAGE:
32 triml.sh FILE [FILE…]
33
34 OPTIONS:
35 (none)
36
37 EXAMPLE:
38 triml.sh
39 triml.sh ./*.txt
40 EOF
41 } # Display information on how to use this script.
42 prompt_continue() {
43 # Desc: Prompt user to go approve/disapprove or list files to be moved.
44 while true; do
45 read -rp "Rename ${#args[@]} files? (y/N or l/list): " choice;
46 case "${choice,,}" in
47 y|yes)
48 yell "STATUS:Renaming...";
49 return 0;
50 ;;
51 l|list)
52 for i in "${!args[@]}"; do
53 yell "Rename: ${args[i]} -> ${args_defront[i]}";
54 done;
55 ;;
56 n|no)
57 die "FATAL:Operation aborted.";
58 ;;
59 *)
60 yell "Invalid option.";
61 esac;
62 done;
63 }; # prompt user to continue operation
64 main () {
65 declare -a args args_defront;
66 declare prefix;
67 declare path_dir name_file name_file_new;
68
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);
73 else
74 ## Act on argument-specified file paths
75 args=("$@");
76 fi;
77
78 # Check that all args are file paths
79 for arg in "${args[@]}"; do
80 if [[ ! -f "$arg" ]]; then
81 show_usage;
82 die "FATAL:Not a file:${arg}"; fi;
83 done;
84
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]}")";
90 done;
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;
96
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}";
103 done;
104
105 # Throw rename warning
106 must prompt_continue;
107
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]}";
112 else
113 die "FATAL:Failed to move ${args[i]} to ${args_defront[i]}";
114 fi;
115 done;
116 };
117 main "$@";
118
119 # Author: Steven Baltakatei Sandoval
120 # License: GPLv3+