Como copiar em cp se a pasta de destino já existir?

7

Exemplo ...

Isso é o que eu quero.

/tmp $ cp -f -R --verbose /tmp/a /tmp/b
'/tmp/a' -> '/tmp/b'
'/tmp/a/file2' -> '/tmp/b/file2'
'/tmp/a/file1' -> '/tmp/b/file1'

Isto é o que eu não quero.

/tmp $ cp -f -R --verbose /tmp/a /tmp/b
'/tmp/a' -> '/tmp/b/a'
'/tmp/a/file2' -> '/tmp/b/a/file2'
'/tmp/a/file1' -> '/tmp/b/a/file1'

Como posso deixar o cp se comportar como se a pasta ainda não existisse?

(Eu não quero deletar de antemão. Apenas alguns arquivos de / tmp / a para serem copiados para / tmp / b sem criar uma sub-pasta dentro de / tmp / b. Então parece que / tmp / b / arquivo1 / tmp / b / arquivo2 e assim por diante.)

    
por James Mitch 01.02.2013 / 20:58

4 respostas

3

O Rsync foi inventado para esse tipo de coisa.

rsync -av --update /source/ /destination

NB: Observe que / source / tem um "/" no final que pega o arquivo1, o arquivo2 e não a pasta em que ele está. / o destino não tem um rastro. Então, sua solução é assim:

rsync -av --update /tmp/a/ /tmp/b
    
por root-11 13.02.2013 / 20:18
8

O sinalizador -T (AKA --no-target-directory ) faz o que você deseja:

$ cp -R --verbose -T /tmp/a /tmp/b
'/tmp/a/file1' -> '/tmp/b/file1'
'/tmp/a/file2' -> '/tmp/b/file2'
    
por Flimm 19.02.2013 / 23:03
6

Assumindo que Bash você pode fazer

( shopt -s dotglob; cp -f -R --verbose /tmp/a/* /tmp/b/ )

O que isto faz é:

  1. ele fará com que globs (o * ) capture arquivos com um ponto na frente. Eles são considerados "ocultos" por convenção.
  2. * será expandido antes que cp consiga ver o comando. Portanto, se houver dois arquivos, como em sua pergunta, a linha de comando expandida será cp -f -R --verbose /tmp/a/file1 /tmp/a/file1 /tmp/b/
  3. finalmente a barra invertida no destino certifica-se de que copia para essa pasta /tmp/b/ .

Esse método também garante que você não precise redefinir a opção do shell, porque ela está sendo executada em uma subcamada. Você pode obter resultados semelhantes colocando-os em um arquivo de script, em vez de executá-los a partir da linha de comando.

    
por 0xC0000022L 13.02.2013 / 20:05
1
$ cp -r --verbose a/. b
'a/.' -> 'b'
'a/./zzz' -> 'b/zzz'

$ cp -r --verbose a/. b
'a/./zzz' -> 'b/./zzz'

Acho que não vi isso descrito em nenhum lugar; Eu estava apenas tentando diferentes possibilidades e encontrei uma que funcionasse. Pelo que sei, é uma conseqüência natural de como /. e cp funcionam. (Ao contrário da sintaxe para rsync , mencionada em outra resposta, que é explicitamente documentada como um caso especial).

    
por sourcejedi 14.02.2013 / 19:58

Tags