Copiando subpastas específicas com estrutura de diretório para uma nova pasta

8

Estou tendo a seguinte estrutura de diretórios:

                Main_Dir
                   |
  -----------------------------------
  Subdir1       Subdir2       Subdir3
     |             |             |
 ---------     ---------     ---------
 |   |   |     |   |   |     |   |   |            
fo1 fo2 f03   fo1 fo2 f03   fo1 fo2 f03

Eu quero copiar todos os subdiretórios ( Subdir1, Subdir2, Subdir3) para uma nova pasta. Mas eu só quero copiar fo1e fo2pastas no novo local.

Não tenho certeza de como isso poderia ser feito.

Shan
fonte
Copie tudo, apague fo3?
ChuckCottrill

Respostas:

4

Se a árvore de diretórios for mais do que apenas ..../f03você pode usar este rsynccomando para copiar todos os fo1& fo2e excluir todos os outros diretórios com o nome fo*.

$ rsync -avz --include='fo[12]/' --exclude='fo*/' \
      Main_Dir/ new_Main_Dir/.

Ao lidar com esses tipos de cenários de cópia, eu sempre uso rsynce é --dry-run& --verboseswitches, para que eu possa ver o que vai fazer sem realmente precisar copiar os arquivos.

$ rsync -avz --dry-run --verbose --include='fo[12]/' --exclude='fo*/' \
      Main_Dir/ new_Main_Dir/.

Exemplo

Funcionamento a seco.

$ rsync -avz --dry-run --include='fo[12]/' --exclude='fo*/' \
      Main_Dir/ new_Main_Dir/.
sending incremental file list
./

Subdir1/
Subdir1/fo1/
Subdir1/fo2/
Subdir2/
Subdir2/fo1/
Subdir2/fo2/
Subdir3/
Subdir3/fo1/
Subdir3/fo2/

sent 201 bytes  received 51 bytes  504.00 bytes/sec
total size is 0  speedup is 0.00 (DRY RUN)

Se você quiser ver algumas das rsynclógicas internas do que está sendo incluído / excluído, use o --verbosecomutador.

$ rsync -avz --dry-run --verbose --include='fo[12]/' --exclude='fo*/' \
      Main_Dir/ new_Main_Dir/.

sending incremental file list
[sender] showing directory Subdir1/fo2 because of pattern fo[12]/
[sender] showing directory Subdir1/fo1 because of pattern fo[12]/
[sender] hiding directory Subdir1/fo3 because of pattern fo*/
[sender] showing directory Subdir2/fo2 because of pattern fo[12]/
[sender] showing directory Subdir2/fo1 because of pattern fo[12]/
[sender] hiding directory Subdir2/fo3 because of pattern fo*/
[sender] showing directory Subdir3/fo2 because of pattern fo[12]/
[sender] showing directory Subdir3/fo1 because of pattern fo[12]/
[sender] hiding directory Subdir3/fo3 because of pattern fo*/
delta-transmission disabled for local transfer or --whole-file
./
Subdir1/
Subdir1/fo1/
Subdir1/fo2/
Subdir2/
Subdir2/fo1/
Subdir2/fo2/
Subdir3/
Subdir3/fo1/
Subdir3/fo2/
total: matches=0  hash_hits=0  false_alarms=0 data=0

sent 201 bytes  received 51 bytes  504.00 bytes/sec
total size is 0  speedup is 0.00 (DRY RUN)

Se você precisar excluir outras formas de diretórios, poderá adicionar várias exclusões.

slm
fonte
3

Use rsync:

rsync -av --exclude="f03" /path/to/Main_Dir/ /pth/to/destination
Radu Rădeanu
fonte
0

Você pode tentar algo como isto:

find Main_Dir -maxdepth 1 -mindepth 1 -type d | while IFS= read -r subdir; do
   mkdir -p new_dir/"$(basename $subdir)" && 
   cp -r "$subdir"/{fo1,fo2} new_dir/"$(basename $subdir)"/; 
done

O findcomando retorna todos os subdiretórios diretos de Main_Dir. basenameretornará o nome do subdiretório encontrado (por exemplo, basename Main_Dir/Subdir1retornos Subdir1). Em seguida, você usa a expansão de chaves do shell para evitar a digitação fo1e fo2várias vezes e as copia para o new_dir/$(basename $subdir)diretório recém-criado .

No caso específico de você mencionar onde há apenas diretórios abaixo Main_Dire onde não há espaços ou caracteres estranhos nos nomes, você pode simplificar o acima para

cd Main_Dir; for subdir in *; do 
  mkdir -p ../new_dir/$subdir && cp -rv $subdir/{fo1,fo2} ../new_dir/$subdir; 
done
terdon
fonte
0

Se sua estrutura de diretórios é exatamente como no seu exemplo (ou seja, todos os foarquivos estão no mesmo nível):

mkdir -p New_Dir/{Subdir1,Subdir2,Subdir3}
for subdir in Subdir1 Subdir2 Subdir3;do
    cp -r Main_Dir/"$dir"/{fo1,fo2} New_Dir/"$dir"/
done
Joseph R.
fonte