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
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.
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
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/{} \;
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).
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
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.
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.)