movendo um (diretório de arquivos |) enquanto evita colisões de nome de arquivo

2

Eu tenho um script bash que move arquivos de vários locais diferentes para uma pasta chamada completed .

Desejo evitar a substituição de arquivos anteriores, portanto, no caso de o nome de um arquivo (por exemplo, Selection Of Recipes.zip ) que desejo mover já estar em completed , adicione um nonce ou outra string ao nome do arquivo para diferencie ( Selection of Recipes-???.zip , onde ??? é uma string aleatória).

Isso é possível com apenas mv , ou devo tentar criar outro script bash com argumentos que lide com esse aspecto? Alguém tem um script bash que eu possa usar como padrão?

    
por taserian 28.07.2014 / 21:13

2 respostas

5

Se você estiver usando o GNU mv , você tem a seguinte opção.

$ mv -b source/* dest/.

Essa opção informa ao mv para enviar todos os arquivos que colidem no diretório dest/. para uma versão de backup, geralmente adicionando um til ( ~ ) ao final do arquivo, antes de mover os arquivos para o diretório .

Exemplo

Digamos que eu tenha os seguintes diretórios de amostra com arquivos.

$ mkdir source dest
$ touch source/file{1..3} dest/file{1..5}

$ tree
.
├── dest
│   ├── file1
│   ├── file2
│   ├── file3
│   ├── file4
│   └── file5
└── source
    ├── file1
    ├── file2
    └── file3

Agora, quando movemos arquivos de source para dest :

$ mv -b source/* dest/.
$ tree 
.
├── dest
│   ├── file1
│   ├── file1~
│   ├── file2
│   ├── file2~
│   ├── file3
│   ├── file3~
│   ├── file4
│   └── file5
└── source

2 directories, 8 files

Controlando a extensão

Mais uma vez com a versão GNU de mv , você pode alterar o comportamento padrão usando a opção -S <string> .

$ mv -b -S "string" source/* dest/.

Exemplo

$ mv -b -S .old source/* dest/.

$ tree 
.
├── dest
│   ├── file1
│   ├── file1.old
│   ├── file2
│   ├── file2.old
│   ├── file3
│   ├── file3.old
│   ├── file4
│   └── file5
└── source

2 directories, 8 files
    
por 28.07.2014 / 22:59
0

Aqui está o script. Se você chamar move , você terá que usar o comando move file destination

#!/bin/bash

FILE=$1
DEST=$2

if 'ls ${DEST}/${FILE} > /dev/null'
then
    base='echo ${FILE} | sed 's/\(.*\)\..*//''
    ext='echo ${FILE} | sed 's/.*\.\(.*\)/''
    r=$RANDOM
    mv ${FILE} ${DEST}/${base}-${r}.${ext}
else
    mv ${FILE} ${DEST}
fi

Você provavelmente deve adicionar alguma validação (como garantir que o arquivo numerado aleatório já não existe) e o fato de o usuário fornecer dois argumentos.

    
por 28.07.2014 / 21:34