Mesclando dois diretórios sem copiar os arquivos

3

Digamos que eu tenha o seguinte:

Folder A
    C1
        file a
    A2

Folder B
     C1
     B2
         file b
     B3

O que eu quero é mesclar essas duas pastas, o que me daria:

Folder C
    C1
    A2
    B2
    B3

Observe que não escrevi file a e file b . Eu só quero mesclar a arquitetura. Cada repositório contém arquivos diferentes e não quero que eles sejam adicionados ao diretório mesclado. Como conseqüência, mv Folder\ A/* Folder\ B não é adequado.

Vocês vêem uma maneira de fazer isso?

    
por fxm 05.09.2013 / 08:46

3 respostas

7

Bem, você poderia ter find exec mkdir .

cd /A/
find -type d -exec mkdir -p /C/{} \;

Ou se a estrutura é plana como mostrado no seu exemplo, sem find

cd /A/
for dir in */
do
    mkdir -p /C/"$dir"
done

e em ambos os casos o mesmo novamente para cd /B/ .

    
por 05.09.2013 / 09:02
2

Se você quiser apenas criar a mesma estrutura de diretório, poderá chamar find para percorrer cada árvore de diretórios existente e chamar mkdir com o argumento correto em cada subdiretório. Chame mkdir -p para pular silenciosamente os diretórios que já existem.

cd 'Folder A'
find . -type d -exec mkdir -p '/path/to/Folder C/{} '\;
cd 'Folder B'
find . -type d -exec mkdir -p '/path/to/Folder C/{} '\;

Em zsh, supondo que Folder A , Folder B e Folder C sejam subdiretórios do mesmo diretório:

mkdir -p Folder\ [AB]/**/*(/e\''REPLY=Folder\ C/${REPLY#*/}'\')

Se você quiser reproduzir a hierarquia de diretórios com permissões de arquivo, poderá chamar rsync e fornecer um filtro que inclua apenas os diretórios e não os arquivos regulares. Não se esqueça de incluir um / no final dos diretórios de origem para que o conteúdo seja copiado diretamente em /path/to/Folder C sem criar /path/to/Folder C/path/to/Folder A e assim por diante.

rsync -a --include='*/' --exclude='*' '/path/to/Folder A/' '/path/to/Folder B/' '/path/to/Folder C'
    
por 06.09.2013 / 02:53
0

Veja como eu faria:

$ (find "Folder A"/* -type d ; find "Folder B"/* -type d) | \
           sed 's#[^/]\+/##' | xargs -I{} mkdir -p "Folder C"/{}

Detalhes

Isso gerará a lista de subdiretórios em "Pasta A" e Pasta B ", e a lista ficará assim:

Folder A/A2
Folder A/C1
Folder B/B2
Folder B/B3
Folder B/C1

Piping que a saída através deste comando sed irá remover o bit "Folder ..":

sed 's#[^/]\+/##'

Resultando nisso:

A2
C1
B2
B3
C1

NOTA: O sed acima está olhando do lado esquerdo, encontrando tudo que não é uma barra, até a primeira barra, esses caracteres são substituídos por nada, essencialmente excluindo-os.

Neste ponto, você precisa apenas de mkdir no diretório "Pasta C", então usaremos xargs para executar esta tarefa repetitiva:

xargs -I{} mkdir -p "Folder C"/{}

Isso diz para pegar cada argumento como {} e substituí-lo no seguinte comando sempre que houver um {} correspondente.

Exemplo

Dados da amostra:

$ tree Folder\ {A,B,C}
Folder A
|-- A2
'-- C1
    '-- filea
Folder B
|-- B2
|   '-- fileb
|-- B3
'-- C1
Folder C

NOTA: Veja "Pasta C" está vazia para começar.

Agora nós executamos nosso comando:

$ (find "Folder A"/* -type d ; find "Folder B"/* -type d) | \
           sed 's#[^/]\+/##' | xargs -I{} mkdir -p "Folder C"/{}

E ficamos com o seguinte:

$ tree Folder\ C
Folder C
|-- A2
|-- B2
|-- B3
'-- C1
    
por 05.09.2013 / 11:29