¿Cómo copiar una estructura de carpetas y hacer enlaces simbólicos a los archivos?


21

Tengo una carpeta SOURCE que contiene varias carpetas de subnivel, cada una con sus propios archivos.

Quiero copiar esta carpeta en una nueva carpeta COPY donde necesito copiar la estructura del directorio pero mantener los archivos como enlaces simbólicos a los archivos originales en SOURCE y sus subcarpetas.



GNU Stow hace un poco esto.
Kusalananda

Respuestas:


27

Aquí está la solución en Linux y Cygwin no integrados:

cp -as SOURCE/ COPY

Tenga en cuenta que SOURCE debe ser una ruta absoluta y tener una barra inclinada final. Si desea dar una ruta relativa, puede usar

cp -as "$(pwd)/SOURCE/" COPY

Funciona perfecto, gracias. Solo una nota ... La FUENTE tiene que ser dada con la ruta completa (COPIA puede ser dada en términos relativos si se desea)
Antonello

¿Cómo hacer que funcione si el directorio fuente se actualizará constantemente con nuevas carpetas y nuevos archivos dentro de ellas? ¿Los enlaces simbólicos a ellos se crearán automáticamente en el directorio de destino en la estructura de carpetas correcta?
SexyBeast

@AttitudeMonger No, un comando como cp solo crea los enlaces una vez (como puede ver en el resultado). Para actualizar el destino automáticamente, deberá monitorear el directorio de origen en busca de cambios.
user905686

¿Se puede hacer esto para crear enlaces relativos?
ctrl-alt-delor

@richard si SOURCE es un camino relativo, entonces creo que sí. Pruébelo y, si esto no funciona, le sugiero que haga una nueva pregunta. Referencia a este por todos los medios.
roaima

6

Hay al menos 2 utilidades estándar para construir un árbol de directorios sombra de un árbol existente, por lo que no es necesario escribir código aquí.

En primer lugar está lndir(1)el xutils-devpaquete. Utiliza enlaces simbólicos a los archivos. Desde la página del manual:

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

Una alternativa quizás mejor es simplemente usar cpcon las opciones correctas como sugiere la respuesta aceptada. Solo daré más detalles útiles con suerte:

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

Si no le importa preservar todos los atributos (propiedades / permisos, tiempos), reemplace la aopción (equivalente a -dr --preserve=all) con r(solo recursivo):

cp -rl /src/dir /dest/dir    # hard-links to leaf-files
cp -rs /src/dir /dest/dir    # symlinks to leaf-files

lndirtambién está disponible como un script de shell aquí en caso de que no esté instalado: opensource.apple.com/source/X11/X11-0.46.4/lndir.sh?txt
Lenar Hoyt

2

Puedes probar un par de comandos de búsqueda 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/{} \;

1

Algo como esto hará lo que necesita.

#!/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

Los directorios se crean en el árbol COPY de destino. Todo lo demás vuelve a la ruta absoluta dentro del árbol SOURCE. Asegúrese de que tanto SOURCE como COPY estén especificadas como rutas absolutas (comenzando por /).

Si tiene que copiar un árbol grande y desea un informe de progreso por directorio, puede agregarlo echo "$ITEM" >&2;justo antes del mkdircomando.

(Miré cpy cpioninguno parece tener una opción para vincular a la fuente con enlaces simbólicos).


1
El comentario de "prueba de línea 9" puede haberse relacionado con ksh en AIX que desea un punto y coma para cerrar la lista entre llaves:{ mkdir -p "$COPY/$ITEM"; continue; }
Jeff Schaller

@JeffSchaller gracias. No escribí un kshguión ... pero parece que eso también es necesario bash. Fijación
roaima

0

Si no hay directorios vacíos en SOURCE que deben copiarse

find /full/path/to/SOURCE -type f -exec cp -t COPY --parents -s {} +
mv COPY/full/path/to/SOURCE COPY
rm -r COPY/full

1
Ya que de cptodos modos estás asumiendo GNU , ¿por qué no cp -as?
Gilles 'SO- deja de ser malvado'

0

Comenzaría por romper el 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::Findes un módulo útil que le permite ejecutar una subrutina específica en cualquier archivo dentro de un árbol de directorios. En este caso, el subcomprueba si es un directorio, y si lo es, hace un mkdiro un archivo, en cuyo caso hace un enlace simbólico.


-1

Parece que estás buscando algo como la herramienta rsnapshot; crea copias de directorios arbitrarios y usa enlaces duros siempre que sea posible. (Eche un vistazo a la página del manual para ver si eso encaja).


No, la pregunta pide explícitamente enlaces simbólicos y rsnapshot usa enlaces duros (ya que es una herramienta de respaldo y los archivos deben mantenerse incluso si se eliminan del directorio de origen).
user905686
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.