Mover arquivos e renomear quando houver um arquivo na pasta de destino

4

Eu costumava fazer isso com Hazel . Eu movi tudo de ~/Downloads/ para ~/Downloads/Archive/Pictures , ~/Downloads/Archive/Documents , ~/Downloads/Archive/Videos etc. baseado na extensão do arquivo, e quando um arquivo com um nome idêntico já existia, Hazel simplesmente acrescentaria um número ao arquivo que ele estava se movendo.

Eu queria escrever um script de shell que conseguisse isso, mas rapidamente percebi que não tinha idéia de como renomear os arquivos sem nenhuma entrada do usuário. O esquema para renomear por poderia ser um contador simples após o nome do arquivo e só deveria ocorrer quando mv sobrescreveria o arquivo existente. Ele também deve ser capaz de continuar o contador, caso já existam várias instâncias com um nome de arquivo idêntico. Portanto, se eu estivesse movendo dirA/file.ext para dirB/ que já tem file.ext e file2.ext , o script deve começar a contar com 3 e renomear dirA/file.ext para dirB/file3.ext .

Alguém pode oferecer alguma orientação sobre como fazer isso? De preferência com um script de shell, mas se não, em Ruby, Perl ou Python. Apenas saber se isso é possível com um script de shell me ajudaria.

    
por Jukka Haav 22.07.2011 / 18:49

3 respostas

8

Não é tão difícil. Se o arquivo de destino existir, você só precisará separar o arquivo no nome de base e na extensão e incrementar um contador até que o novo nome de arquivo não exista no diretório de destino.

source=dirA/file.ext
dest_dir=dirB

file=$(basename file.ext)
basename=${file%.*}
ext=${file##*.}

if [[ ! -e "$dest_dir/$basename.$ext" ]]; then
    # file does not exist in the destination directory
    mv "$source" "$dest_dir"
else
    num=2
    while [[ -e "$dest_dir/$basename$num.$ext" ]]; do
        (( num++ ))
    done
    mv "$source" "$dest_dir/$basename$num.$ext" 
fi 
    
por 22.07.2011 / 21:15
3

Você também pode fazer isso com um único comando se tiver a versão GNU de mv instalada em cada estação de trabalho. O padrão fornecido com o Mac OS X não suporta a opção --backup . Você pode obter o GNU Coreutils para Mac OS X através de Macports e muitos outros locais.

Então é só uma questão de:

mv --backup=numbered dirA/file.ext dirB/

O nome do arquivo resultante será file.ext.~1~ , file.ext.~2~ e assim por diante.

    
por 22.07.2011 / 21:55
0

Graças a glenn, reescrevi a funcionalidade para que ela suporte extensões vazias e também aceita arquivos diretos como o destino (assim como o% normal mv )

mv_no_override() {
    local dir file ext base num
    if [ -d "$2" ]; then
        dir=$2
        file=$(basename "$1")
    else
        dir=$(dirname "$2")
        file=$(basename "$2")
    fi
    ext="$(sed -r 's/.+(\..+)|.*//' <<<"$file")"
    base="$(sed -r 's/(.+)\..+|(.*)//' <<<"$file")"
    while [ -e "$dir/$base$num$ext" ]; do
        (( num++ ))
    done
    mv "$1" "$dir/$base$num$ext"
}
    
por 16.09.2017 / 09:39