Eu tenho um diretório de muitos arquivos, algo como 50.000 pdf e outros arquivos em um servidor. Eu preciso mover os específicos para outro diretório. Posso gerar uma lista dos arquivos que precisam ser movidos em csv ou em qualquer outro formato de texto.
O que preciso fazer é executar um script bash e mover ou copiar os arquivos listados no arquivo de texto para outro diretório.
Existe uma maneira fácil de fazer isso? Todas as sugestões ou recursos serão muito apreciados.
Respostas:
rsync tem várias opções que podem levar uma lista de arquivos para processo (
--files-from
,--include-from
, etc.).Por exemplo, isso fará o truque:
fonte
rsync -a /source/directory --files-from=/full/path/to/listfile /destination/directory
Para evitar um uso inútil de
cat
(e se você não usarrsync
):Isso manipulará qualquer nome de arquivo válido, a menos que contenha uma nova linha, se os arquivos estiverem listados um por linha.
fonte
mv
todos os arquivos será recolhido no mesmo diretório de destino. Arsync
abordagem na resposta aceita não sofre essa limitação.assumindo o bash, além de
listoffiles
conter um arquivo por linha. Minha única objeção à rota rsync é que o OP solicita um método de mover os arquivos, sem copiá-los. O rsync tem mais bandeiras do que um casamento real, por isso tenho certeza de que pode ser modificado ainda mais, mas às vezes mais simples é melhor!fonte
while read -r file; do mv "$file" /path/of/destination ; done < listoffiles
Isso depende do formato do arquivo de texto que você possui. Por exemplo, se você tiver a lista de arquivos gravados de forma que Cada arquivo esteja localizado em uma nova linha. Você pode usar xargs como:
Além disso, você pode usar o
find
comando com a-exec
opção copiar / mover os arquivos.fonte
O Rsync tem o benefício adicional sobre os comandos
cp
oumv
porque ele criará pastas automaticamente se elas não existirem.fonte
/path/to/source
necessário quando utiliza os caminhos da lista de arquivos?Eu acho que a resposta do rsync é melhor, mas apenas para outra opção:
fonte
Eu acidentalmente copiei o conteúdo completo de um diretório em um diretório de destino em vez de mover o diretório completo. Isso resultou em um diretório de destino desordenado, em vez de o diretório de origem ser adicionado ao diretório.
Para corrigir isso, fiz o seguinte:
ls -rt /path/to/cluttered/destination/directory/ > /opt/dircheck/filestomove
O comando acima cria o arquivo filestomove que será uma lista de todo o conteúdo do diretório de destino, classificado inversamente por tempo, significando do mais antigo para o mais recente.Em seguida, criei um subdiretório do diretório de destino agora desordenado para mover o material.
mkdir /path/to/cluttered/destination/directory/newsubdirectory
Depois, repeti a listagem do diretório, exceto a listagem na tela e a exibição de mais detalhes.
ls -lrht /path/to/cluttered/destination/directory/
Esta linha lista o diretório, classificado por data crescente (classificação inversa por hora) e mostra mais informações, incluindo a data / hora de cada arquivo no diretório de destino agora desordenado. Refiro-me a isso, começando no topo para mostrar quais diretórios e arquivos eu quero manter onde eles estavam. Haverá uma lacuna no carimbo de data / hora dos arquivos em que todos os novos arquivos iniciam e que não deveriam estar lá.Em seguida, editei o arquivo de gravação de arquivo criado na primeira etapa acima (que é classificada por data) e excluí alguns da lista que estavam lá anteriormente e quero permanecer no diretório original.
vim /opt/dircheck/filestomove
Exclua da parte superior todos os arquivos que você não deseja mover.Em seguida, usei o comando listado anteriormente nesta postagem para mover os arquivos da minha lista para o novo diretório que criei.
sudo xargs -a /opt/dircheck/filestomove mv -t /path/to/cluttered/destination/directory/newsubdirectory
Isso moveu todos os arquivos em uma fração de segundo. (Nota: você pode não precisar do sudo no início, isso é uma questão de permissões de arquivo).
Agora, meu diretório de destino original é agradável e limpo e contém um novo diretório com todos os arquivos e diretórios que o estavam atrapalhando.
fonte
Se (e somente se), você não possui caracteres desagradáveis nos nomes de arquivos (espaços, novas linhas, o que confundiria xargs sobre como dividir as coisas em argumentos individuais) e gera uma lista de arquivos separados por novas linhas (um arquivo por linha), você poderia fazer algo assim.
(Em geral, veja man xargs , é incrível)
Se o seu mv em particular não tiver a opção -t, você também poderá fazer alguns truques como
Nota - nenhum deles funcionará como esperado se houver nomes de arquivos com novas linhas.
fonte
cp
,mv
e similares não têm-t
opção nos bsd 's, e o segundo exemplo com subshell não funcionou para mim (/path/to/move
é anexado como o último nome do arquivo)(cat filenames.txt; echo; echo /path/to/move/files/to) | xargs mv
Tente algo como:
fonte
while read line; do mv $line /images; done < list.txt
como um único comandoO seguinte funcionou para mim, onde eu precisava copiar todos os arquivos PNG de um caminho específico (e todos os subdiretórios) para um novo local, preservando a estrutura de diretórios:
Como o RSYNC cria o espelho da estrutura de diretórios primeiro e depois sincroniza os arquivos, você pode acabar com pastas em excesso que estão vazias. Eu usei o sinalizador --prune-empty-dirs para remover esses diretórios vazios.
Não tenho afiliação, mas achei correto dar crédito à fonte que inspirou essa solução: http://techblog.zabuchy.net/2011/transfer-only-selected-file-types-with-rsync/
fonte