Qual é a maneira mais rápida de mover um milhão de imagens de um diretório para outro no Linux?


14

Eu tenho um milhão de imagens que ocupam 30 GB de espaço em disco que precisam ser movidas de um diretório local para outro diretório local.

Qual seria a maneira mais eficiente de fazer isso? Usando mv? Usando cp? Usando rsync? Algo mais?

Eu preciso tomar estes:

/path/to/old-img-dir/*
                     00000000.jpg
                     --------.jpg  ## nearly 1M of them! ##
                     ZZZZZZZZ.jpg

e mova-os aqui:

/path/to/new/img/dir/

5
Eu não acho que você possa vencer mv, em termos de desempenho, se os diretórios de origem e de destino residirem no mesmo sistema de arquivos.
Frédéric Hamidi

Respostas:


26

rsync seria uma péssima escolha, pois faz muito trabalho em segundo plano cliente / servidor, responsável por sistemas locais e remotos.

mvé provavelmente a melhor escolha. Se possível, você deve tentar em mv directory_old directory_newvez de mv directory_old/* directory_new/. Dessa forma, você move uma coisa em vez de um milhão de coisas.


6
+1 para o conselho para mover os diretórios em vez dos arquivos.
Ex-Umbris

4
Além disso, a expansão de curinga provavelmente quebraria os argumentos máximos suportados mvse estivermos falando de milhões.
slhck

6
O rsync lida bem com transferências na mídia de armazenamento local. Ele força coisas como --whole-file (removendo a implementação do algoritmo delta xfer) e evita outras coisas como --compression que não serve para nada nas transferências locais. Se os diretórios residirem em diferentes sistemas de arquivos, o 'mv' não fornecerá nenhum tipo de desempenho. Se eles residem no mesmo sistema de arquivos, basta 'mv' os diretórios como essas pessoas disseram.
UtahJarhead

Se houver muitas imagens, o uso de um curinga simples do shell excederá a linha de comando máxima.
Raúl Salinas-Monteagudo

1
Mover entre discos ainda moverá todos os dados. No mesmo disco, mvapenas atualiza informações inode assim mv directory_old directory_newfunciona mais rápido do quemv directory_old/* directory_new
Anshul

14
find src_image_dir/ -type f -name '*.jpg' -print0 | xargs -0r mv -t dst_image_dir/ 
  • Isso não excederá a expansão do argumento.
  • Você pode especificar a extensão do arquivo, se desejar. (-name ...)
  • find -print0com xargs -0permite que você use espaços nos nomes.
  • xargs -rnão será executado a mvmenos que haja algo a ser movido. ( mvreclamará se nenhum arquivo de origem for fornecido).
  • A sintaxe mv -tpermite especificar primeiro o destino e, em seguida, os arquivos de origem, necessários xargs.
  • Mover o diretório inteiro é obviamente muito mais rápido, pois ocorre em tempo constante, independentemente do número de arquivos contidos nele, mas:
    • o diretório de origem desaparecerá por uma fração de tempo e poderá criar problemas para você;
    • se o processo estiver usando o diretório atual como diretório de saída (ao contrário de sempre se referir a um caminho completo a partir de um local não móvel), você teria que reiniciá-lo. (como você faz com a rotação de logs ).

A propósito, gostaria de me perguntar se realmente preciso mover uma quantidade tão grande de arquivos de uma só vez. O processamento em lote é superestimado. Tento não acumular grandes quantidades de trabalho se puder processar as coisas no momento em que são geradas.


Isso funciona bem o suficiente para mover arquivos entre sistemas de arquivos no mesmo servidor. Bem o suficiente para não me incomodar em procurar solução no rsync. Claro que demorou uma ou duas horas, mas funciona. Uma coisa a observar, se você der um nome para o diretório, em vez de "." - certifique-se de usar a barra final no comando find, caso contrário, o diretório será recriado no destino do comando mv.
Speeddymon

7

Se os dois diretórios residirem no mesmo sistema de arquivos, use mvno DIRECTORY e não o conteúdo do diretório.

Se eles residirem em dois sistemas de arquivos diferentes, use rsync:

rsync -av /source/directory/ /destination

Observe a trilha /na fonte. Isso significa que ele copiará o CONTEÚDO do diretório e não o próprio diretório. Se você deixar /desativado, ele ainda copiará os arquivos, mas eles permanecerão em um diretório chamado /destination/directory. Com o /, os arquivos estarão apenas em/destination

rsyncmanterá a propriedade do arquivo se você executá-lo como root ou se os arquivos pertencerem a você. Ele também manterá o mtimearquivo de cada arquivo individual.


2
Para copiar uma pasta grande de um disco rígido para outro, rsyncparece rodar em círculos mv. Obrigado pela dica!
Leo-the-manic

2
tar cf - dir1 | (cd dir2; tar xf -)

tar cf - dir1 | ssh remote_host "( cd /path/to/dir2; tar xf - )"

Quando você usa 'cp', cada arquivo faz um abrir-ler-fechar-abrir-gravar-fechar. O Tar usa processos diferentes para leitura e gravação, além de vários passos para operar em vários arquivos ao mesmo tempo. Mesmo em uma única caixa de CPU, os aplicativos multithread são mais rápidos.


2
Embora isso possa responder à pergunta, seria uma resposta melhor se você pudesse fornecer uma explicação sobre o motivo .
DavidPostill

1
Se eles estiverem na máquina local, é provável que residam no mesmo sistema de arquivos. Ao usar, tar c | tar xvocê obtém um custo de O (total_size) em vez de O (file_count).
Raúl Salinas-Monteagudo

1

Como directory_old e directory_new estão no mesmo sistema de arquivos que você poderia usar em cp -lvez de mvcomo uma opção. cp -lcriará links físicos para os arquivos originais. Quando você terminar de 'mover' e ficar satisfeito com o resultado, poderá remover esses arquivos do diretório_old. em termos de velocidade, será o mesmo que 'mv' quando você primeiro criar os links e depois remover os originais. Mas essa abordagem permite que você comece do começo, se isso faz sentido


0

Depende (tm). Se o seu sistema de arquivos for copiar na gravação, a cópia ( cpou rsync, por exemplo) deve ser comparável a uma movimentação. Mas, nos casos mais comuns, move ( mv) será o mais rápido, pois pode simplesmente alternar entre os dados que descrevem onde um arquivo é colocado (nota: isso é simplificado demais).

Então, em sua instalação média do Linux, eu usaria mv.

EDIT: @ Frédéric Hamidi tem um bom argumento nos comentários: Isso só é válido se ambos estiverem no mesmo sistema de arquivos e disco. Caso contrário, os dados serão copiados de qualquer maneira.


0

Para copiar pelo menos ~ 10k de arquivos (sem diretórios), a cp reclamou:

incapaz de executar / bin / cp: lista de argumentos muito longa

A melhor opção é Rsync:

destino de origem rsync

E foi feito muito rapidamente!


0

Se você tiver espaço livre, arquive-os em um único arquivo .tar (sem compactação é mais rápida) e mova o arquivo e desarquive-o.


0

A natureza do destino determinaria a maneira mais eficiente de executar esta tarefa. Vamos supor que você esteja em um sistema local, você PWDestá /no momento. e /acontém os milhões de imagens. Nossa tarefa é mover todas as imagens para /b, mantendo toda a estrutura de subdiretórios. Vamos também assumir /ae /bsão pontos de montagem para duas partições diferentes, cada uma em um disco conectado localmente. Nós gostaríamos de fazer esta tarefa com um tarpipe. Isso pode levar algum tempo, por isso certifique-se que você está usando screen, tmuxou você executar este como um processo de fundo.

tar -C /a -cf . | tar -C /b -xf -

Isso copiaria todos os arquivos e diretórios /apara /b, então agora você precisará limpar uma /avez que confirme a conclusão sem erros.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.