Como faço para mover milhares de arquivos de uma lista?

3

Então, eu tenho uma lista de arquivos em um arquivo de texto. Eu acredito que são cerca de 100.000 arquivos.

Os arquivos da lista estão espalhados por vários diretórios, têm diferentes tamanhos, nomes de arquivos, extensões, idades, etc.

Estou tentando encontrar uma maneira de mover esses arquivos e apenas esses para outra unidade.

Complicating factor: alguns dos arquivos têm o mesmo nome, mas não são o mesmo arquivo. Eles não podem simplesmente ser movidos para uma pasta com uma política de sobrescrita ou ignorando para múltiplos.

De preferência, gostaria que eles retivessem sua estrutura de diretórios, mas apenas os arquivos que eu quero dentro do diretório de destino. (a unidade de destino não é grande o suficiente para simplesmente copiar tudo).

Abaixo está um exemplo de algumas linhas no arquivo de texto que tem os nomes dos arquivos de origem:

media/dave/xdd/cruzer/F#(NTFS 1)/Raw Files/Portable Network Graphic file/3601-3900/FILE3776.PNG/Windows/winsxs/amd64_microsoft-windows-o..disc-style-memories_31bf3856ad364e35_6.1.7600.16385_none_51190840a935f980/Title_mainImage-mask.png
media/dave/xdd/d1/other/hd1/Program Files/DVD Maker/Shared/DvdStyles/Memories/Title_content-background.png

Eu tentei usar

rsync -av 'cat /sourcefile.txt' /media/destinationhdd

que reclama que há muitos argumentos.

rsync -a --files-from=/sourcefile.txt / /media/destinationhdd

e

cat /sourcefile.txt | xargs -n 200 rsync -av % /media/destinationhdd

No entanto, isso apenas tenta copiar meu diretório raiz para o destino.

Como copio apenas os arquivos específicos que eu quero?

    
por Ne Mo 11.08.2014 / 21:09

3 respostas

2

Aqui está um pequeno script de shell para você:

#!/bin/sh

while read line
do
    DIR='dirname "$line"'
    mkdir -p "/$DIR"
    mv "$line" "/$DIR"
done < 

Uso (supondo que você salvou o script como script.sh e tornou executável com chmod +x script.sh ):

./script.sh input.txt output_directory

Ele moverá todos os arquivos listados em input.txt para output_directory , usando os caminhos originais, por exemplo, para que input.txt tenha a seguinte lista:

test.txt
dir1/test.txt
Another Test/something_else.txt

Os arquivos serão movidos para:

output_directory/test.txt
output_directory/dir1/test.txt
output_directory/Another Test/something_else.txt

Eu fiz alguns testes antes de postar esta resposta, mas por favor certifique-se de tentar em uma amostra menor primeiro para confirmar que está funcionando como esperado!

    
por kraxor 11.08.2014 / 22:47
1

O script a seguir primeiro copia o diretório estrutura da fonte, depois os arquivos da sua lista para as pastas correspondentes. A linha if not line in ["", "\n"] é para evitar erros, caso a lista de arquivos contenha linhas vazias.

#!/usr/bin/env python

import os
import shutil

source = "/path/to/source"; target = "/path/to/target"; filelist = "/path/to/filelist.txt"

for root, dirs, files in os.walk(source):
    for dr in dirs:
        dr = root+"/"+dr
        destdir = dr.replace(source, target)
        if not os.path.exists(destdir):
            os.makedirs(destdir)

with open(filelist) as lines:
    src = lines.readlines()

for line in src:
    if not line in ["", "\n"]:
        shutil.copyfile(line.replace("\n", ""),
            line.replace("\n", "").replace(source, target))

Como usar

  • Copie o script em um arquivo vazio e salve-o como move.py
  • Adicione os caminhos apropriados na seção principal
  • Execute:

    python /path/to/move.py
    
por Jacob Vlijm 12.08.2014 / 00:34
0

Você pode fazer isso com xargs com bastante facilidade.

mkdir /newroot/
<filenames.txt xargs -I% bash -c 'mkdir -p /newroot/$(dirname "%" && cp "%" "/newroot/%"'

O problema é garantir que a nova estrutura de diretórios exista. Para isso, usamos dirname para obter os nomes dos diretórios, mkdir -p para construí-los e, finalmente, cp (ou mv ) para copiar / mover de um para o outro. Eu deixei no modo de cópia para que você possa testar.

Sugiro testar se find /newroot/ -type f | wc -l e wc -l filenames.txt fornecem o mesmo número depois.

    
por Oli 12.08.2014 / 15:17