Existe um comando 'cp' para verificar dados e remover arquivos?

0

Eu tenho alguns arquivos de foto no meu telefone e estou fazendo backup deles em uma unidade externa. (Tudo está montado em um laptop linux.)

Eu copiei os arquivos, quando eu realmente deveria ter mv os editado.

No entanto, como fiz isso, gostaria de verificar os dados copiados corretamente para cada arquivo e, em seguida, removê-lo do meu telefone se o arquivo tiver sido copiado sem erros.

Então, o que realmente estou procurando é um comando cp ou mv like que:

  • Copia o arquivo, se ele não existir no destino
  • Verifica os dados entre a origem e o destino (depois de copiar, se o arquivo ainda não existir)
  • Se ambos os arquivos forem idênticos em binário, remova o arquivo da origem

Eu pensei que eu poderia fazer isso com rsync , mas eu dei uma olhada nas várias opções de exclusão e nenhuma delas combinou com "delete o arquivo na fonte " , em vez disso, essas opções excluem os arquivos antes / depois / durante (?) no destino .

    
por user3728501 16.07.2017 / 14:10

2 respostas

1

(Nota: rsync --remove-source-files é o comando que eu estava procurando, exceto que ele não verifica dados.)

Em relação à comparação binária, descobri que diff pode fazer isso:

No diretório de origem:

for f in *.jpg; do diff $f "/path/to/destination/$f"; done

Isso compara arquivos binários na origem e no destino. Nenhuma saída = os arquivos não diferem.

Isso pode ser usado para verificar dados.

Como diff retorna 0 no caso em que nenhuma diferença foi encontrada, pode-se fazer

for f in *.jpg; do diff $f "/desination/$f" && rm $f; done

Isso removerá o arquivo $f na pasta de origem se diff retornar 0 , isto é; os arquivos são binários iguais.

Pode ser útil fazer com que isso pareça um novo comando, vamos chamá-lo de verify-rm .

Como tenho o Dropbox instalado, colocarei meus scripts na minha pasta do Dropbox para não ter que me preocupar em fazer o backup deles quando eu reinstalar o sistema operacional dentro de 6 meses ...

$ cd ~/Dropbox && mkdir my-scripts && cd my-scripts
$ vim verify-rm

Aqui está o meu script verify-rm :

if [ "$#" -lt 2 ];
then
    echo "Bad arguments, use like cp command"
else
    success=0
    fail=0
    error=0
    for arg in ${@:1:$(($#-1))}
    do
        #echo "$arg ${@:(-1):1}"
        diff "$arg" "${@:(-1):1}"
        ret=$?
        if [ $ret -eq 0 ]
        then
            success=$((success+1))
            echo "Verified file $arg"
            rm $arg
        elif [ $ret -eq 1 ]
        then
            fail=$((fail+1))
            echo "Binary files $arg and ${@:(-1):1} differ"
        else
            error=$((error+1))
            echo "diff exited with error: code=$ret"
        fi
    done
    echo "Summary: $success files verified and ok"
    echo "         $fail files differ!"
    echo "         $error errors"
    echo "Files which differ not removed"
    echo "Files where diff returned error code not removed"
fi

Torne o script executável

$ chmod +x verify-rm

Em seguida, use o novo script ("comando")

$ verify-rm /path/to/source/*.jpg /path/to/destination

Tenho notado que os arquivos com espaços no nome do arquivo não são processados corretamente, pois o bash trata cada conjunto de caracteres entre espaços como um argumento diferente. Não tenho certeza do que fazer sobre isso, ou se isso pode ser corrigido.

No entanto, tem sido apontado nos comentários que rsync --remove-source-files também funcionará, e rsync funciona corretamente quando há espaços nos nomes dos arquivos, e eu notei que é muito mais rápido também, então eu recomendo apenas usar rsync .

    
por 16.07.2017 / 14:14
0

Você mencionou meu comentário sobre rsync --remove-source-files , mas se quiser sua resposta de script ainda mais aqui estão algumas dicas:

Se você quiser apenas fazer uma comparação booleana de quaisquer dois arquivos, incluindo binário, há algumas rotas mais diretas do que o padrão diff . Por um lado, cmp faz uma comparação byte a byte de dois arquivos. Ou você pode simplesmente comparar seus checksums com, por exemplo,

diff -q <(cksum file1) <(cksum file2)

Quanto aos espaços em seus nomes de arquivos, esse é um problema bem conhecido com uma variedade de possíveis soluções. Este é um resumo bastante abrangente das coisas: link . Se você não está planejando compartilhar seu roteiro, basta escolher a alternativa que mais lhe convier.

    
por 16.07.2017 / 20:01