# rename files to strip all special characters. # usage: name [FILES] name() { local targets=("${@}") # target file(s). local count=0 # processed count. local total=${#} # total to process. # all targets except hidden by default. if [[ "${targets}" = "" ]]; then targets=([^.]*) total=${#targets[@]} fi # process. for target in "${targets[@]}"; do # increment counter. ((count++)) # parse new name. local ext="" local name="${target}" # ext only for files. if [[ -f "${target}" ]]; then ext=".${target##*.}" name="${target%.*}" fi local new_name=$(parse_simplify "${name}")${ext} # status line. local status="[${count}/${total}] ${target} -> ${new_name}" # check if same name. if [[ "${target}" = "${new_name}" ]]; then echo -e "${color_green}${status}: no change.${color_default}" continue fi # check if target name already exists. if [[ -f "${new_name}" ]]; then echo -e "${color_red}${status}: already exists!${color_default}" return 1 fi # rename target. mv -- "${target}" "${new_name}" &> /dev/null # show change. echo "${status}" done } # rename all files to their hashes while keeping extensions. # usage: name_hash [FILES] name_hash() { local targets=("${@}") # target file(s). local count=0 # processed counter. local total=${#} # total to process. # all targets except hidden by default. if [[ "${targets}" = "" ]]; then targets=([^.]*) total=${#targets[@]} fi # process. for target in "${targets[@]}"; do # process only targets. [[ -f "${target}" ]] || continue # increment count. ((count++)) # extract extension. local extension="${target##*.}" if [[ "${extension}" = "${target}" ]]; then extension="" else extension=".${extension}" fi # hash the new name. local hash=$(sha1sum -- "${target}" | cut -d\ -f1) new_name="${hash,,}${extension}" # prepare status. local status="[${count}/${total}] ${target} -> ${new_name}" # check if same name. if [[ "${target}" = "${new_name}" ]]; then echo -e "${color_green}${status}: no change.${color_default}" continue fi # rename target. mv -- "${target}" "${new_name}" &> /dev/null # show change. echo -e "${status}" done } # check hashes for renamed files. # usage: name_hash_check [FILES] name_hash_check() { local targets=("${@}") # target file(s). local total=${#} # total to process. local count=0 # processed counter. local failed=0 # failed to process counter. # all targets by default. if [[ "${targets}" = "" ]]; then targets=([^.]*) total=${#target[@]} fi # process. for target in "${targets[@]}"; do # process only targets. if [[ -f "${target}" ]]; then # increment count. ((count++)) # status info. local status="[${count}/${total}] ${target}" # extract hashes. local stored="${target%%.*}" local actual=$(sha1sum -- "${target}" | cut -d\ -f1) # compare hashes. if [[ "${stored}" = "${actual}" ]]; then echo -e "${status}: OK." else echo -e "${color_red}${status}: failed.${color_default}" ((failed++)) fi fi done # report result. if [[ ${count} -gt 1 ]]; then if [[ ${failed} -gt 0 ]]; then echo -e "${color_bred}Items failed to validate: ${failed}.${color_default}" else echo -e "${color_green}All successful.${color_default}" fi fi } # rename files for Jellyfin series, i.e. Episode S01E01.mkv # usage: name_series name_series() { local season="${1}" # season number. local targets="${@:2}" # target files. local count=0 # processed counter. local total=${#} # total to process. # error when no season number specified. if [[ "${season}" = "" ]]; then echo "usage: name_series " return 1 fi # all targets by default. if [[ "${targets}" = "" ]]; then targets=([^.]*) total=${#targets[@]} fi # process. for target in "${targets[@]}"; do # process only targets. if [[ -f "${target}" ]]; then # increment episode number. ((count++)) # extract new name. local new_name="Episode S${season}E$(printf %02d ${count}).${target##*.}" # prepare status. local status="[${count}/${total}] ${target} -> ${new_name}" # rename target. mv -- "${target}" "${new_name}" &> /dev/null echo -e "${status}" fi done } # rename files for Kavita manga format. # usage: name_manga name_manga() { local season="${1}" # season number. local targets="${@:2}" # target files. local count=0 # processed counter. local total=${#} # total to process. local manga="${PWD##*/}" # manga name. # error when no season number specified. if [[ "${season}" = "" ]]; then echo "usage: name_manga " return 1 fi # all targets by default. if [[ "${targets}" = "" ]]; then targets=([^.]*) total=${#targets[@]} fi # process. for target in "${targets[@]}"; do # process only targets. if [[ -f "${target}" ]]; then # increment episode number. ((count++)) # extract new name. local new_name="${manga} Vol.${season} Ch.${count}.${target##*.}" # prepare status. local status="[${count}/${total}] ${target} -> ${new_name}" # rename target. mv -- "${target}" "${new_name}" &> /dev/null echo -e "${status}" fi done } # rename files for new extension. # usage: name_ext [FILES] name_ext() { local extension="${1}" # new extension. local targets="${@:2}" # target file(s). local count=0 # processed counter. local total=${#} # total to process. # remove extension name from total files. ((total--)) # error when no new extension specified. if [[ "${extension}" = "" ]]; then echo "usage: name_ext [targets]" return 1 fi # all targets by default. if [[ "${targets}" = "" ]]; then targets=([^.]*) total=${#targets[@]} fi # process. for target in "${targets[@]}"; do # process only targets. if [[ -f "${target}" ]]; then # increment count. ((count++)) # extract new name. local new_name="${target%.*}"."${extension}" # rename target. mv -- "${target}" "${new_name}" &> /dev/null # show change. echo "[${count}/${total}] ${target} -> ${new_name}" fi done } # export for parallel. export -f name name_hash name_hash_check name_ext