Copia apenas pastas e não arquivos?

12

Existe uma maneira de copiar um diretório inteiro, mas apenas as pastas? Eu tenho um arquivo corrompido em algum lugar do meu diretório, o que está causando falhas em meus discos rígidos.

Então, em vez de copiar o arquivo corrompido para outro disco rígido, eu queria apenas copiar as pastas, porque tenho scripts que pesquisam centenas de pastas e não quero ter que criá-las manualmente.

Eu pesquisei o manual do CP, mas não vi nada (eu posso ter perdido)

Digamos que eu tenha essa estrutura no meu disco rígido com falha:

dir1
    files
    dir2
        files
        files
        dir4
dir3
files

Tudo que eu quero é a estrutura de diretórios, e não quaisquer arquivos.

Então eu acabaria no novo disco rígido:

dir1
    dir2
        dir4
dir3

Esperando que alguém conheça alguns truques!

    
por Shannon 25.10.2013 / 23:33

2 respostas

12

Se você quiser espelhar um esqueleto de diretório e copiar nenhum arquivo:

find -type d -links 2 -exec mkdir -p "/path/to/backup/{}" \;

O que está acontecendo aqui:

  • Localizar apenas selecionando diretórios
  • Estamos usando -links 2 para encontrar os diretórios mais detalhados possíveis .
  • mkdir -p fará com que todos os diretórios ausentes sejam exibidos ao longo do caminho.

Eu fiz assim, em vez de find -type d -exec mkdir -p "/path/to/backup/{}" \; , porque isso vai reduzir o custo total de mkdir de chamadas. Podemos rapidamente provar isso com um pequeno teste. Aqui está a árvore de teste seguida pelo que eu corri para comparar os dois comandos:

$ tree
.
├── dir1
│   ├── dir2
│   │   └── dir3
│   ├── dir7
│   └── dir8
└── dir9
    └── dir0

$ pr -m -t <(find -type d) <(find -type d -links 2)
.                               ./dir1/dir8
./dir1                          ./dir1/dir2/dir3
./dir1/dir8                     ./dir1/dir7
./dir1/dir2                     ./dir9/dir0
./dir1/dir2/dir3
./dir1/dir7
./dir9                  
./dir9/dir0 

E isso só vai melhorar em uma solução de palavras reais com milhares de diretórios.

    
por Oli 25.10.2013 / 23:46
1

Muito facilmente feito com o one-liner do python:

bash-4.3$ tree
.
├── ABC
├── set_pathname_icon.py
├── subdir1
│   ├── file1.abc
│   └── file2.abc
├── subdir2
│   ├── file1.abc
│   └── file2.abc
└── subdir3
    └── subdir4
        └── file1.txt

4 directories, 7 files
bash-4.3$ python -c 'import os,sys;dirs=[ r for r,s,f in os.walk(".") if r != "."];[os.makedirs(os.path.join(sys.argv[1],i)) for i in dirs]' ~/new_destination
bash-4.3$ tree ~/new_destination
/home/xieerqi/new_destination
├── subdir1
├── subdir2
└── subdir3
    └── subdir4

Como script, isso pode ser reescrito da seguinte forma:

#!/usr/bin/env python
import os,sys
dirs=[ r for r,s,f in os.walk(".") if r != "."]
for i in dirs:
    os.makedirs(os.path.join(sys.argv[1],i)) 
    
por Sergiy Kolodyazhnyy 13.07.2017 / 07:20

Tags