Invocando o cp de dentro do BASH e usando a opção -u

2

Existe uma maneira de ter a opção cp --update imprimir arquivos que não foram copiados porque o diretório de origem continha uma versão mais nova do arquivo?

    
por l0b0 15.04.2012 / 03:59

3 respostas

5

Substitua cp -ur por rsync -urvv .

Os dois "v" -s não são um erro de digitação: eles estão lá para maior detalhamento, para mostrar os arquivos que foram ignorados.

Os arquivos ignorados serão parecidos com the_filename is newer , então, para obter a lista de arquivos ignorados, você pode usar este verso:

rsync -urvv source/ target | grep ' is newer$' | sed -e 's/ is newer$//'

Ou se você for usá-lo interativamente, o --progress flag pode ser muito útil.

    
por 17.04.2012 / 20:02
1

Eu não acho que haja uma maneira de ter cp fazer isso diretamente, mas isso deve fazer essencialmente a mesma coisa:

cp -vu file destination | awk '{ gsub("['\x27]", "", $1); print $1 } END { if (NR == 0) print "NOFILES" }' | xargs -I{} find . ! -name {} -maxdepth 1

Este pequeno liner vem com algumas limitações:

1) Depende de não haver arquivos com o nome "NOFILES". Você pode alterar essa sequência no comando awk para atender às suas necessidades.

2) Você deve estar no diretório em que file existe. Se você não estiver nesse diretório, será necessário alterar o comando find para find dirWhereFileExists em vez de find . . Se você não estiver copiando de um único diretório, poderá usar find dir1 dir2... .

3) Não funcionará se você, por algum motivo, tiver backticks ou aspas simples em seus nomes de arquivos.

Como você pode ver, esta não é a solução mais robusta, mas deve ser uma operação única.

EDITAR

Eu acordei esta manhã e percebi que a solução acima era lixo. Se você tentar copiar vários arquivos, ele pesquisará quantas vezes tiver arquivos, excluindo um arquivo de cada vez. A seguinte solução, no entanto, deve funcionar:

cp -vu file destination | awk '{ gsub("['\x27]", "", $1); regex = $1 "|" regex } END { if (NR == 0) { regex = "NOFILES|" } print ".*/("substr(regex, 0, length(regex))")" }' | xargs -I{} find . -regextype posix-extended ! -regex {} -maxdepth 1

Ele cria um regex e passa para find . As mesmas limitações acima aplicam-se.

Desculpe pelo peido cerebral mais cedo. Acho que era tarde demais para estar no StackOverflow.

    
por 15.04.2012 / 04:04
0

O rsync faria o trabalho para você? Tem muitas opções que se encaixam na sua descrição, digamos "não sobrescrever arquivos mais novos" e tal. E você pode ter as descobertas do log. Eu uso frequentemente para cópia de arquivos remotos e locais.

Você também pode ficar muito granular com isso.

Boa sorte.

    
por 17.04.2012 / 18:49

Tags