This repository has been archived on 2024-03-04. You can view files and clone it, but cannot push or open issues or pull requests.
linux/.config/bash/module/Name.sh

396 lines
8.6 KiB
Bash
Raw Normal View History

# Rename dirs to `snake_case` and files to `PascalCase`. Careful with structured file names like archives!
# Usage: name [FILES]
function name() {
local IFS=$'\n'
local targets=(${@})
[[ "${targets}" = "" ]] && targets=($(ls))
process() {
# Skip archive.
if $(_is_archive ${target}); then
_iterate_skip "File is an archive, skip."
return 0
fi
if [[ -d "${target}" ]]; then
local new_name=$(parse_snake ${target})
[[ -e "${new_name}" ]] && return 0
mv -- ${target} ${new_name} && echo ${new_name}
else
local ext=".${target##*.}"
local name=${target%.*}
[[ "${ext}" = ".${target}" ]] && ext=""
local new_name="$(parse_pascal ${name})${ext}"
[[ -e "${new_name}" ]] && return 0
mv -- ${target} ${new_name} && echo ${new_name}
fi
}
_iterate_targets process ${targets[@]}
}
# Rename files with provided parser, i.e. `parse_simple`.
2023-12-07 04:02:47 +03:00
# All files by default.
# Usage: name_parse <PARSER> [FILES]
function name_parse() {
2023-12-05 21:50:45 +03:00
local IFS=$'\n'
local parser=${1}
local targets=(${@:2})
2023-12-17 16:27:21 +03:00
[[ "${targets}" = "" ]] && targets=([^.]*)
2023-12-05 21:50:45 +03:00
if [[ "${parser}" = "" ]]; then
help name_parse
return 2
fi
2023-12-17 16:27:21 +03:00
process() {
# Skip archive.
if $(_is_archive ${target}); then
_iterate_skip "File is an archive, skip."
return 0
fi
2023-12-05 21:50:45 +03:00
# parse new name.
local ext=""
local name="${target}"
# ext only for files.
if [[ -f "${target}" ]]; then
ext=".${target##*.}"
name="${target%.*}"
fi
2023-12-05 21:50:45 +03:00
# Files w/o extension support.
[[ "${ext#.}" = "${name}" ]] && ext=""
# Get new name.
local new_name=$(${parser} "${name}")${ext,,}
2023-12-05 21:50:45 +03:00
# check if same name.
2023-12-17 16:27:21 +03:00
[[ "${target}" = "${new_name}" ]] && return 0
2023-12-05 21:50:45 +03:00
# check if target name already exists.
if [[ -f "${new_name}" ]]; then
2023-12-17 16:27:21 +03:00
_error "${new_name}: Already exists!"
return 1
2023-12-05 21:50:45 +03:00
fi
# rename target.
mv -- "${target}" "${new_name}" && echo "${new_name}"
2023-12-17 16:27:21 +03:00
}
2023-12-05 21:50:45 +03:00
2023-12-17 16:27:21 +03:00
_iterate_targets process ${targets[@]}
2023-08-08 16:24:15 +03:00
}
2023-12-07 04:02:47 +03:00
# Rename all files to their hashes while keeping extensions.
# All files by default.
# Usage: name_hash [FILES]
2023-12-07 01:44:42 +03:00
function name_hash() {
2023-12-05 21:50:45 +03:00
local IFS=$'\n'
2023-12-17 16:27:21 +03:00
local targets=(${@})
[[ "${targets}" = "" ]] && targets=($(_ls_file))
2023-12-05 21:50:45 +03:00
2023-12-17 16:27:21 +03:00
process() {
2023-12-05 21:50:45 +03:00
# extract extension.
local extension="${target##*.}"
if [[ "${extension}" = "${target}" ]]; then
extension=""
else
extension=".${extension}"
fi
# hash the new name.
2023-12-07 22:37:08 +03:00
local hash=$(pv "${target}" | sha1sum | cut -d\ -f1)
2023-12-05 21:50:45 +03:00
new_name="${hash,,}${extension,,}"
2023-12-05 21:50:45 +03:00
# check if same name.
2023-12-17 16:27:21 +03:00
[[ "${target}" = "${new_name}" ]] && return 0
2023-12-05 21:50:45 +03:00
# rename target.
2023-12-17 16:27:21 +03:00
mv -- ${target} ${new_name} && echo ${new_name}
}
2023-12-17 16:27:21 +03:00
_iterate_targets process ${targets[@]}
2023-08-08 16:24:15 +03:00
}
2023-12-07 04:02:47 +03:00
# Check hashes for previously renamed files.
# All files by default.
# Usage: name_hash_check [FILES]
2023-12-07 01:44:42 +03:00
function name_hash_check() {
2023-12-05 21:50:45 +03:00
local IFS=$'\n'
2023-12-17 16:27:21 +03:00
local targets=(${@})
[[ "${targets}" = "" ]] && targets=([^.]*)
2023-12-05 21:50:45 +03:00
2023-12-17 16:27:21 +03:00
process() {
2023-12-05 21:50:45 +03:00
# extract hashes.
local stored="${target%%.*}"
2023-12-07 22:37:08 +03:00
local actual=$(pv "${target}" | sha1sum | cut -d\ -f1)
2023-12-05 21:50:45 +03:00
# compare hashes.
if [[ "${stored}" != "${actual}" ]]; then
2023-12-17 20:12:33 +03:00
_error "Failed."
2023-12-17 16:27:21 +03:00
return 1
2023-12-05 21:50:45 +03:00
fi
2023-12-17 16:27:21 +03:00
}
2023-12-05 21:50:45 +03:00
2023-12-17 16:27:21 +03:00
_iterate_targets process ${targets[@]}
2023-08-08 16:24:15 +03:00
}
2024-01-18 00:26:43 +03:00
# Rename files for Jellyfin shows, i.e. `Episode S01E01.mkv`
2023-12-07 04:02:47 +03:00
# All files by default.
2024-01-18 00:26:43 +03:00
# Usage: name_show [FILES]
function name_show() {
2023-12-05 21:50:45 +03:00
local IFS=$'\n'
local season="$(realpath .)"; season="${season##*\ }"
2023-12-05 23:56:04 +03:00
local episode=0
local targets=(${@})
2023-12-17 16:27:21 +03:00
[[ "${targets}" = "" ]] && targets=($(_ls_file))
2023-12-05 21:50:45 +03:00
2023-12-17 16:27:21 +03:00
# Error when no season number specified.
2023-12-05 21:50:45 +03:00
if [[ "${season}" = "" ]]; then
_error "Could not determine season number."
2023-12-05 21:50:45 +03:00
return 2
fi
2023-12-17 16:27:21 +03:00
process() {
2023-12-05 21:50:45 +03:00
((episode++))
# extract new name.
local new_name="Episode S${season}E$(printf %02d ${episode}).${target##*.}"
2023-12-17 16:27:21 +03:00
# Skip on no change.
[[ "${target}" = "${new_name}" ]] && return 0
2023-12-05 21:50:45 +03:00
# rename target.
2023-12-17 16:27:21 +03:00
mv -- ${target} ${new_name} && echo ${new_name}
}
2023-12-17 16:27:21 +03:00
_iterate_targets process ${targets[@]}
2023-08-08 16:24:15 +03:00
}
2023-12-07 04:02:47 +03:00
# Rename files for Kavita manga format.
# All files by default.
# Usage: name_manga <SEASON> [FILES]
2023-12-07 01:44:42 +03:00
function name_manga() {
2023-12-05 21:50:45 +03:00
local IFS=$'\n'
2023-12-17 16:27:21 +03:00
local manga=${PWD##*/}
local season=${1}
2023-12-05 23:56:04 +03:00
local episode=0
2023-12-17 16:27:21 +03:00
local targets=(${@:2})
[[ "${targets}" = "" ]] && targets=($(_ls_file))
2023-12-05 21:50:45 +03:00
2023-12-17 16:27:21 +03:00
# Error when no season number specified.
2023-12-05 21:50:45 +03:00
if [[ "${season}" = "" ]]; then
help name_manga
2023-12-05 21:50:45 +03:00
return 2
fi
2023-12-17 16:27:21 +03:00
process() {
2023-12-05 21:50:45 +03:00
((episode++))
2023-12-17 16:27:21 +03:00
# Extract new name.
2023-12-05 21:50:45 +03:00
local new_name="${manga} Vol.${season} Ch.${episode}.${target##*.}"
2023-12-17 16:27:21 +03:00
# Skip on no change.
[[ "${target}" = "${new_name}" ]] && return 0
2023-12-05 21:50:45 +03:00
2023-12-17 16:27:21 +03:00
# Rename target.
mv -- ${target} ${new_name} && echo ${new_name}
}
2023-12-05 21:50:45 +03:00
2023-12-17 16:27:21 +03:00
_iterate_targets process ${targets[@]}
2023-08-08 16:24:15 +03:00
}
2024-01-18 00:17:11 +03:00
# Rename files for ffmpeg_music_meta format.
# All files by default.
# Usage: name_music [FILES]
function name_music() {
local IFS=$'\n'
local targets=(${@})
[[ "${targets}" = "" ]] && targets=($(ls))
process() {
# Extract new name.
2024-01-18 00:24:23 +03:00
local ext=${target##*.}
2024-01-22 12:25:17 +03:00
if [[ -d "${target}" ]]; then
local new_name="$(parse_titlecase $(parse_simple ${target%.*}))"
2024-01-22 12:25:17 +03:00
else
local new_name="$(parse_titlecase $(parse_simple ${target%.*})).${ext}"
2024-01-22 12:25:17 +03:00
fi
2024-01-18 00:17:11 +03:00
# Skip on no change.
[[ "${target%/}" = "${new_name}" ]] && return 0
# Rename target.
mv -- ${target} ${new_name} && echo ${new_name}
}
_iterate_targets process ${targets[@]}
}
2023-12-07 04:02:47 +03:00
# Rename files with new extension.
# All files by default.
# Usage: name_ext <EXTENSION> [FILES]
2023-12-07 01:44:42 +03:00
function name_ext() {
2023-12-05 21:50:45 +03:00
local IFS=$'\n'
2023-12-17 16:27:21 +03:00
local extension=${1}
local targets=(${@:2})
[[ "${targets}" = "" ]] && targets=($(_ls_file))
2023-12-05 21:50:45 +03:00
2023-12-17 16:27:21 +03:00
# Error when no new extension specified.
2023-12-05 21:50:45 +03:00
if [[ "${extension}" = "" ]]; then
2023-12-07 04:31:18 +03:00
help name_ext
2023-12-05 21:50:45 +03:00
return 2
fi
2023-12-17 16:27:21 +03:00
process() {
# Extract new name.
2023-12-05 21:50:45 +03:00
local new_name="${target%.*}"."${extension}"
2023-12-17 16:27:21 +03:00
# Skip on no change.
[[ "${target}" = "${new_name}" ]] && return 0
2023-12-05 21:50:45 +03:00
2023-12-17 16:27:21 +03:00
# Rename target.
mv -- ${target} ${new_name} && echo ${new_name}
}
2023-12-05 21:50:45 +03:00
2023-12-17 16:27:21 +03:00
_iterate_targets process ${targets[@]}
2023-08-08 16:24:15 +03:00
}
2023-12-07 04:02:47 +03:00
# Change file name prefix.
# All matching files by default.
2023-11-26 00:51:57 +03:00
# Usage: name_prefix <OLD> <NEW> [FILES]
2023-12-07 01:44:42 +03:00
function name_prefix() {
2023-12-05 21:50:45 +03:00
local IFS=$'\n'
2023-12-17 16:27:21 +03:00
local old=${1}
local new=${2}
local targets=(${@:3})
[[ "${targets}" = "" ]] && targets=(${old}*)
2023-12-05 21:50:45 +03:00
2023-12-17 16:27:21 +03:00
process() {
2023-12-05 21:50:45 +03:00
# Create new name.
local new_name="${new}${target#$old}"
2023-12-17 16:27:21 +03:00
# Skip on no change.
[[ "${target}" = "${new_name}" ]] && return 0
2023-12-05 21:50:45 +03:00
# Rename.
2023-12-17 16:27:21 +03:00
mv -- ${target} ${new_name} && echo ${new_name}
}
2023-12-17 16:27:21 +03:00
_iterate_targets process ${targets[@]}
2023-11-08 16:47:12 +03:00
}
2023-12-07 04:02:47 +03:00
# Change file name postfix.
# All matching files by default.
2023-11-26 00:51:57 +03:00
# Usage: name_postfix <OLD> <NEW> [FILES]
2023-12-07 01:44:42 +03:00
function name_postfix() {
2023-12-05 21:50:45 +03:00
local IFS=$'\n'
2023-12-17 16:27:21 +03:00
local old=${1}
local new=${2}
local targets=(${@:3})
[[ "${targets}" = "" ]] && targets=(*${old})
2023-12-05 21:50:45 +03:00
2023-12-17 16:27:21 +03:00
process() {
2023-12-05 21:50:45 +03:00
# Create new name.
local new_name="${target%$old}${new}"
2023-12-17 16:27:21 +03:00
# Skip on no change.
[[ "${target}" = "${new_name}" ]] && return 0
2023-12-05 21:50:45 +03:00
# Rename.
2023-12-17 16:27:21 +03:00
mv -- ${target} ${new_name} && echo ${new_name}
}
2023-12-05 21:50:45 +03:00
2023-12-17 16:27:21 +03:00
_iterate_targets process ${targets[@]}
2023-11-26 00:51:57 +03:00
}
2023-11-30 06:07:01 +03:00
# Replace part of the name.
2023-12-07 04:02:47 +03:00
# All matching files by default.
# Usage: name_replace <OLD> <NEW> [FILES]
2023-12-07 01:44:42 +03:00
function name_replace() {
2023-12-05 21:50:45 +03:00
local IFS=$'\n'
2023-12-17 16:27:21 +03:00
local old=${1}
local new=${2}
local targets=(${@:3})
[[ "${targets}" = "" ]] && targets=(*${old}*)
2023-12-05 21:50:45 +03:00
2023-12-17 16:27:21 +03:00
process() {
2023-12-05 21:50:45 +03:00
# Create new name.
local new_name="${target//$old/$new}"
2023-12-17 16:27:21 +03:00
# Skip on no change.
[[ "${target}" = "${new_name}" ]] && return 0
2023-12-05 21:50:45 +03:00
# Rename.
2023-12-17 16:27:21 +03:00
mv -- ${target} ${new_name} && echo ${new_name}
}
2023-12-17 16:27:21 +03:00
_iterate_targets process ${targets[@]}
}
# Fix numbering for numbered files. I.e if there are 10 items and some of them start without zero, then append zero to it. 1..10 -> 01..10.
# Usage: name_fix_numbering [FILES]
function name_fix_numbering() {
local IFS=$'\n'
2023-12-17 16:27:21 +03:00
local highest=0
local power=0
2023-12-17 16:27:21 +03:00
local targets=(${@})
[[ "${targets}" = "" ]] && targets=($(ls | grep "^[0-9]"))
# Count leading zeroes.
for target in "${targets[@]}"; do
2023-12-10 07:26:04 +03:00
# Check that starts with a digit.
[[ "${target}" =~ ^[0-9] ]] || continue
2024-01-03 18:50:59 +03:00
local digits=($(parse_ints "${target}"))
local digit="${digits[0]}"
digit=$((10#${digit}))
[[ "${digit}" -gt "${highest}" ]] && highest="${digit}"
done
local i=${highest}
while [[ i -gt 0 ]]; do
((power++))
i=$((${i}/10))
done
2023-12-17 16:27:21 +03:00
process() {
# Check that starts with a digit.
if [[ ! "${target}" =~ ^[0-9] ]]; then
2023-12-17 16:27:21 +03:00
_error "Does not start with a digit!"
return 1
fi
# Prepare new name.
2024-01-03 18:50:59 +03:00
local digits=($(parse_ints "${target}"))
local digit="${digits[0]}"
digit=$((10#${digit}))
local new_name=$(printf "%0${power}d" "${digit}")"${target#${digits[0]}}"
2023-12-17 16:27:21 +03:00
# Skip if the same name.
[[ "${target}" = "${new_name}" ]] && return 0
# Check that file does not exist.
if [[ -e "${new_name}" ]]; then
2023-12-17 16:27:21 +03:00
_error "${new_name}: File exists!"
return 1
fi
2023-12-17 16:27:21 +03:00
mv -- ${target} ${new_name} && echo ${new_name}
}
2023-12-17 16:27:21 +03:00
_iterate_targets process ${targets[@]}
2023-11-30 06:07:01 +03:00
}
2023-12-17 23:46:41 +03:00
function _comp_name_parse() {
_autocomplete_first_ls $(find_function | grep ^parse)
}
complete -o filenames -F _comp_name_parse name_parse