find + xargs - copia / move arquivos de um subdiret para outro

2

Minha estrutura de pastas é assim:

/volume1
  /photoTest
    /folderA
      /@eaDir
      /eaDir_tmp 
    /folderB
      /@eaDir
      /eaDir_tmp 
    /folder with space
      /@eaDir
      /eaDir_tmp 

O que estou tentando fazer é copiar os arquivos de cada eaDir_tmp para sua respectiva pasta @eaDir .

Consegui fazer isso acontecer:

for a in $(find /volume1/photoTest -type d -name eaDir_tmp); do rsync -vhar --chmod=a+rwx $a/ $a/../@eaDir; done;

até eu atingir a pasta com espaços. O script acima simplesmente adivinha.

Depois de muita pesquisa, eu tentei:

find /volume1/photoTest -type d -name eaDir_tmp -print0 | xargs -0 rsync -vhra --chmod=a+rwx {} {}/../@eaDir

A execução a seco deste comando é executada sem problemas. Mas a corrida real fica paralisada depois de imprimir isso.

sending incremental file list
@eaDir/subdir1/

E fica preso nele.

ps -elf | grep rsync mostra vários processos rsync em wait e poll_s state.

Alguém tem alguma ideia do que está acontecendo? E qual a solução? Eu gostaria de mover os arquivos eventualmente, mas tentar com a cópia primeiro ser menos destrutivo se as coisas correrem mal.

Além disso, posso trabalhar com 2 comandos com muita fealdade:

# first, copy all files via:    
find /volume1/photo -type d -name eaDir_tmp -exec cp -a -t {}/../@eaDir {}/. \;

# second, change file permissions:    
find /volume1/photo -type d -name @eaDir -exec chmod 777 {} -R \;

Mas isso é lento e leva o dobro do tempo, para não mencionar é muito limitante comparado ao que o rsync pode fazer.

Algumas informações básicas:

  • O que há dentro de eaDir pastas? Mais pastas e, em seguida, alguns arquivos dentro deles. Se isso ajuda, a coisa toda começou com isso: link . O autor sugere excluir as pastas @eaDir existentes e simplesmente renomear eaDir_tmp . Mas não posso fazer isso porque as pastas existentes contêm arquivos que gostaria de manter. Eu posso explicar, mas acho que isso vai enlamear ainda mais a questão.
  • Isso está dentro do meu Synology NAS, DSM 6.0+, que eu acho que está rodando o BusyBox? Não tenho certeza.
  • Se os arquivos de destino existirem, eu gostaria de sobrescrevê-lo se a origem for mais recente. Caso contrário, não.
por Mrchief 31.12.2017 / 08:25

2 respostas

0

Usando o Bash:

for a in volume1/photoTest/*
   do 
      pushd "$a"/eaDir_tmp
      cp -u * ../@eaDir          #... or rsync --chmod...
      popd 
   done
    
por 31.12.2017 / 15:46
0
find /volume1/photoTest -type d -name eaDir_tmp -prune \
    -exec sh -c 'rsync -a "$1"/ "${1%/*}/@eaDir"' sh {} ';' \
    -o -type d -name @eaDir -prune

Isso procuraria todos os diretórios cujo nome é eaDir_tmp ou abaixo de /volume1/photoTest . Para cada diretório, o seguinte comando seria executado:

rsync -a "$1"/ "${1%/*}/@eaDir"

em que $1 é o nome do caminho do diretório encontrado. A substituição do parâmetro ${1%/*} removeria o último componente do nome do caminho, girando, e. /volume1/photoTest/folderA/eaDir_tmp into /volume1/photoTest/folderA (você também pode usar "$( dirname "$1" )" ).

Nós removemos o diretório eaDir_tmp e @eaDir da lista de pesquisa quando os encontramos, impedindo que find os digitasse. Isso é feito com -prune .

Ative todas as outras opções para rsync que você acha que deseja.

Com um find que aceita -execdir :

find /volume1/photoTest -type d -name eaDir_tmp -prune \
    -execdir rsync -a eaDir_tmp/ @eaDir ';' \
    -o -type d -name @eaDir -prune

Relacionados:

por 22.06.2018 / 10:17