Como copiar uma estrutura de pastas e criar links simbólicos para arquivos?

21

Eu tenho uma pasta SOURCE que contém várias pastas de subnível, cada uma com seus próprios arquivos.

Eu quero copiar esta pasta em uma nova pasta COPY, onde eu preciso copiar a estrutura de diretórios, mas manter os arquivos como links simbólicos para os arquivos originais em SOURCE e suas subpastas.

    
por Antonello 16.04.2015 / 10:26

7 respostas

24

Aqui está a solução para Linux e Cygwin não embarcados:

cp -as SOURCE/ COPY

Observe que SOURCE deve ser um caminho absoluto e ter uma barra final. Se você quiser dar um caminho relativo, você pode usar

cp -as "$(pwd)/SOURCE/" COPY
    
por 16.04.2015 / 15:32
5

Existem pelo menos 2 utilitários padrão para construir uma árvore de diretórios sombra de uma árvore existente, portanto não há necessidade de escrever código aqui.

Primeiro, há lndir(1) do pacote xutils-dev . Ele usa links simbólicos para arquivos. Na página do manual:

NAME
   lndir  -  create a shadow directory of symbolic links to another
             directory tree
SYNOPSIS
   lndir [ -silent ] [ -ignorelinks ] [ -withrevinfo ] fromdir [ todir ]

Uma alternativa talvez melhor é simplesmente usar cp com as opções certas, como a resposta aceita sugere. Vou apenas dar mais alguns detalhes úteis:

cp -al /src/dir /dest/dir    # hard-links to leaf-files
cp -as /src/dir /dest/dir    # symlinks to leaf-files

Se você não se importa em preservar todos os atributos (propriedades / permissões, horas), substitua a opção a (equivalente a -dr --preserve=all ) com r (apenas recursivo):

cp -rl /src/dir /dest/dir    # hard-links to leaf-files
cp -rs /src/dir /dest/dir    # symlinks to leaf-files
    
por 30.09.2015 / 23:22
2

Você pode tentar alguns comandos de busca como este:

mkdir FULL-PATH-TO-COPY
cd SOURCE
find . \( ! -regex '\.' \) -type d -exec mkdir FULL-PATH-TO-COPY/{} \;
find * -type f -exec ln -s 'pwd'/{} FULL-PATH-TO-COPY/{} \;
    
por 17.04.2015 / 04:23
2

Algo parecido com isso fará o que você precisa.

#!/bin/bash
#
SOURCE="$1" COPY="$2"
cd "$SOURCE"
find . |
    sed 's!^\./!!' |
    while IFS= read ITEM
    do
        test -d "$ITEM" && { mkdir -p "$COPY/$ITEM"; continue; }
        BASE="${FILE%\/*}"
        ( cd "$COPY/$BASE" && ln -s "$SOURCE/$ITEM" )
    done

Os diretórios são criados na árvore COPY de destino. Todo o resto é ligado de forma simbólica ao caminho absoluto dentro da árvore SOURCE. Certifique-se de que SOURCE e COPY estejam especificados como caminhos absolutos (começando com / ).

Se você tiver uma árvore grande para copiar e quiser um relatório de andamento por diretório, adicione echo "$ITEM" >&2; antes do comando mkdir .

(Eu olhei para cp e cpio , mas nenhum parece ter uma opção para vincular à fonte com links simbólicos).

    
por 16.04.2015 / 15:17
0

Se não houver dirs vazios em SOURCE que precisam ser copiados

find /full/path/to/SOURCE -type f -exec cp -t COPY --parents -s {} +
mv COPY/full/path/to/SOURCE COPY
rm -r COPY/full
    
por 16.04.2015 / 11:07
0

Eu começaria quebrando o perl:

#!/usr/bin/perl

use strict;
use warnings;
use File::Find;

my $src_dir = "/full_path/to/dir";
my $tgt_dir = "/path/to/new/location";

sub link_or_mkdir {

    #current file is directory
    if (-d) {
        #extract the path
        my $newpath = $File::Find::dir;
        #change the path so 'old' and 'new' are swapped
        $newpath =~ s,^$src_dir,$tgt_dir,g;
        #print the command to make a new dir (doesn't actually do it)
        print "mkdir -p $newpath\n";
    }
    if (-f) {
        my $new_file = $File::Find::name;
        #change the path so 'old' and 'new' are swapped
        $new_file =~ s,^$src_dir,$tgt_dir,g;
        #print the symlink command
        print "ln -s $File::Find::name $new_file\n";
    }
}

find( \&link_or_mkdir, $tgt_dir );

File::Find é um módulo útil que permite executar uma sub-rotina específica em qualquer arquivo dentro de uma árvore de diretórios. Neste caso, a sub-verificação verifica se é um diretório - e se é, faz um mkdir ou um arquivo - nesse caso, ele faz um symlink.

    
por 16.04.2015 / 11:16
-1

Parece que você está procurando algo parecido com a ferramenta rsnapshot ; cria cópias de diretórios arbitrários e usa hardlinks sempre que possível. (Dê uma olhada na man page para ver se isso se encaixa.)

    
por 16.04.2015 / 10:37