# rename files to strip all special characters. # usage: name [FILES] name() { local IFS=$'\n' local targets=("${@}") # target file(s). local count=0 # processed count. local total=${#} # total to process. local failed=0 # 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 # Files w/o extension support. [[ "${ext#.}" = "${name}" ]] && ext="" # Get new name. local new_name=$(parse_simplify "${name}")${ext,,} # status line. local status="[${count}/${total}] ${target} -> ${new_name}" echo -e "${status}" # check if same name. [[ "${target}" = "${new_name}" ]] && continue # check if target name already exists. if [[ -f "${new_name}" ]]; then echo -e "${color_bred}${status}: already exists!${color_default}" ((failed++)) fi # rename target. mv -- "${target}" "${new_name}" if [[ ${?} != 0 ]]; then echo -e "${color_bred}${status}: Failed.${color_default}" ((failed++)) fi done if [[ ${failed} != 0 ]]; then echo -e "${color_bred}Failed: ${failed}.${color_default}" false fi } # rename all files to their hashes while keeping extensions. # usage: name_hash [FILES] name_hash() { local IFS=$'\n' local targets=("${@}") # target file(s). local count=0 # processed counter. local total=${#} # total to process. local failed=0 # all files except hidden by default. if [[ "${targets}" = "" ]]; then targets=($(ls --classify | grep -v /\$)) total=${#targets[@]} fi # process. for target in "${targets[@]}"; do # 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}" echo -e "${status}" continue fi # show change. echo -e "${status}" # rename target. mv -- "${target}" "${new_name}" if [[ ${?} != 0 ]]; then echo -e "${color_bred}${status}: Failed.${color_default}" ((failed++)) fi done if [[ ${failed} != 0 ]]; then echo -e "${color_bred}Failed: ${failed}.${color_default}" false fi } # check hashes for renamed files. # usage: name_hash_check [FILES] name_hash_check() { local IFS=$'\n' local targets=("${@}") # target file(s). local total=${#} # total to process. local count=0 # processed counter. local failed=0 # all targets by default. if [[ "${targets}" = "" ]]; then targets=($(ls --classify | grep -v /\$)) total=${#targets[@]} fi # process. for target in "${targets[@]}"; do # increment count. ((count++)) # status info. local status="[${count}/${total}] ${target}" echo -e "${status}" # extract hashes. local stored="${target%%.*}" local actual=$(pv "${target}" | sha1sum | cut -d\ -f1) # compare hashes. if [[ "${stored}" != "${actual}" ]]; then echo -e "${color_bred}${status}: Failed.${color_default}" ((failed++)) fi done if [[ ${failed} != 0 ]]; then echo -e "${color_bred}Failed: ${failed}.${color_default}" false fi } # rename files for Jellyfin series, i.e. Episode S01E01.mkv # usage: name_series [FILES] name_series() { local IFS=$'\n' local season="${1}" # Season number. local targets=("${@:2}") # Target files. local count=0 # Processed counter. local episode=0 # Current episode count. local total=${#} # Total to process. local failed=0 # error when no season number specified. if [[ "${season}" = "" ]]; then echo "usage: name_series [FILES]" return 2 fi # all targets by default. if [[ "${targets}" = "" ]]; then targets=($(ls --classify | grep -v /\$)) total=${#targets[@]} fi # process. for target in "${targets[@]}"; do # increment episode number. ((count++)) ((episode++)) # extract new name. local new_name="Episode S${season}E$(printf %02d ${episode}).${target##*.}" # prepare status. local status="[${count}/${total}] ${target} -> ${new_name}" echo -e "${status}" # Warning on no change. [[ "${target}" = "${new_name}" ]] && continue # rename target. mv -- "${target}" "${new_name}" if [[ ${?} != 0 ]]; then echo -e "${color_bred}${status}: Failed.${color_default}" ((failed++)) fi done if [[ ${failed} != 0 ]]; then echo -e "${color_bred}Failed: ${failed}.${color_default}" false fi } # rename files for Kavita manga format. # usage: name_manga [FILES] name_manga() { local IFS=$'\n' local season="${1}" # Season number. local targets=("${@:2}") # Target files. local count=0 # Processed counter. local episode=0 # Current episode count. local total=${#} # Total to process. local manga="${PWD##*/}" # Manga name. local failed=0 # error when no season number specified. if [[ "${season}" = "" ]]; then echo "usage: name_manga [FILES]" return 2 fi # all targets by default. if [[ "${targets}" = "" ]]; then targets=($(ls --classify | grep -v /\$)) total=${#targets[@]} fi # process. for target in "${targets[@]}"; do # increment episode number. ((count++)) ((episode++)) # extract new name. local new_name="${manga} Vol.${season} Ch.${episode}.${target##*.}" # prepare status. local status="[${count}/${total}] ${target} -> ${new_name}" echo -e "${status}" # Warning on no change. [[ "${target}" = "${new_name}" ]] && continue # rename target. mv -- "${target}" "${new_name}" if [[ ${?} != 0 ]]; then echo -e "${color_bred}${status}: Failed.${color_default}" ((failed++)) fi done if [[ ${failed} != 0 ]]; then echo -e "${color_bred}Failed: ${failed}.${color_default}" false fi } # rename files for new extension. # usage: name_ext [FILES] name_ext() { local IFS=$'\n' local extension="${1}" # new extension. local targets=("${@:2}") # target file(s). local count=0 # processed counter. local total=$((${#}-1)) # total to process. local failed=0 # error when no new extension specified. if [[ "${extension}" = "" ]]; then echo "Usage: name_ext [FILES]" return 2 fi # all targets by default. if [[ "${targets}" = "" ]]; then targets=($(ls --classify | grep -v /\$)) total=${#targets[@]} fi # process. for target in "${targets[@]}"; do # increment count. ((count++)) # extract new name. local new_name="${target%.*}"."${extension}" # Prepare status. local status="[${count}/${total}] ${target} -> ${new_name}" echo -e "${status}" # Warning on no change. [[ "${target}" = "${new_name}" ]] && continue # rename target. mv -- "${target}" "${new_name}" if [[ ${?} != 0 ]]; then echo -e "${color_bred}${status}: Failed.${color_default}" ((failed++)) fi done if [[ ${failed} != 0 ]]; then echo -e "${color_bred}Failed: ${failed}.${color_default}" false fi } # Change file's prefixes. # Usage: name_prefix [OLD] [NEW] [FILES] name_prefix() { local IFS=$'\n' local old="${1}" # Old prefix. local new="${2}" # New prefix. local targets=("${@:3}") # Target files. local count=0 # Total files processed. local total=$((${#}-2)) # Total files to process. local failed=0 # All targets by default. if [[ "${targets}" = "" ]]; then targets=([^.]*) total=${#targets[@]} fi # Process. for target in "${targets[@]}"; do # Increment counter. ((count++)) # Create new name. local new_name="${new}${target#$old}" # Prepare status. local status="[${count}/${total}] ${target} -> ${new_name}" echo -e "${status}" # Warning on no change. [[ "${target}" = "${new_name}" ]] && continue # Rename. mv -- "${target}" "${new_name}" if [[ ${?} != 0 ]]; then echo -e "${color_bred}${status}: Failed.${color_default}" ((failed++)) fi done if [[ ${failed} != 0 ]]; then echo -e "${color_bred}Failed: ${failed}.${color_default}" false fi } # export for parallel. export -f name name_hash name_hash_check name_ext