A seguinte função (testada no bash) tentará mover seu primeiro parâmetro para seu segundo parâmetro. Ele espera (e testa) o primeiro parâmetro para ser um arquivo e o segundo para ser um diretório.
A variável "namemax" local deve ser ajustada ao NAME_MAX
do seu sistema de arquivos.
moveshort() {
local namemax=8
# simple sanity checks
[ "$#" -eq 2 ] || return 1
local src=$1
[ -e "$src" ] || return 2
local dest=$2
[ -d "$dest" ] || return 3
local extension=${src##*.}
local basename=${src%.*}
# the base name has ($namemax - $extension - 1)
# characters available to it (1 for the period)
local maxbase=$((namemax - ${#extension} - 1))
# shorten the name, if necessary
basename=${basename:0:maxbase}
# echo "Shortened name: ${basename}.${extension}"
# find a new name, if necessary
if [ -e "${dest}/${basename}.${extension}" ]
then
local index=1
local lenindex=${#index}
#local newbase=${basename:0:-lenindex}
local newbase=${basename:0:maxbase - lenindex}
# loop as long as a conflicting filename exists and
# we're not out of space in the filename for the index
while [ -e "${dest}/${newbase}${index}.${extension}" -a "${#index}" -lt "$maxbase" ]
do
index=$((index + 1))
lenindex=${#index}
newbase=${newbase:0:maxbase - lenindex}
done
if [ -e "${dest}/${newbase}${index}.${extension}" ]
then
echo "Failed to find a non-colliding new name for $src in $dest" >&2
return 4
fi
basename=${newbase}${index}
# echo "new name = ${basename}.${extension}"
fi
# perform the move
mv -- "$src" "${dest}/${basename}.${extension}"
}
Após as verificações de integridade, a função salva a extensão e o nome de arquivo base restante e, em seguida, determina quantos caracteres estão disponíveis para o nome do arquivo base a ser usado.
Se o nome de arquivo fornecido já for muito longo, cortamos os caracteres extras.
Se o nome abreviado já existir no destino, começamos o looping, começando em 1, gerando um novo nome de arquivo base até ficar sem espaço no nome de arquivo base ou encontrarmos um arquivo que não existe. O novo nome de arquivo base é espremido pelo índice conforme o índice cresce.
Se ficarmos sem espaço no nome do arquivo, a função exibe um erro e retorna; caso contrário, ele tentará executar o mv
.