Comment copier une structure de dossiers et créer des liens symboliques vers des fichiers?

21

J'ai un dossier SOURCE qui contient plusieurs dossiers de sous-niveau, chacun avec ses propres fichiers.

Je veux copier ce dossier dans un nouveau dossier COPY où je dois copier la structure du répertoire mais garder les fichiers sous forme de liens symboliques vers les fichiers d'origine dans SOURCE et ses sous-dossiers.

Antonello
la source
1
Voir aussi stackoverflow.com/q/1240636/905686 .
user905686
GNU Stow le fait un peu.
Kusalananda

Réponses:

27

Voici la solution sur Linux non intégré et Cygwin:

cp -as SOURCE/ COPY

Notez que SOURCE doit être un chemin absolu et avoir une barre oblique de fin. Si vous voulez donner un chemin relatif, vous pouvez utiliser

cp -as "$(pwd)/SOURCE/" COPY
roaima
la source
Fonctionne parfaitement, merci. Juste une note .. SOURCE doit être donnée avec le chemin complet (COPY peut être donné à la place en termes relatifs si on le souhaite)
Antonello
Comment le faire fonctionner si le répertoire source sera constamment mis à jour avec de nouveaux dossiers et de nouveaux fichiers à l'intérieur? Les liens symboliques vers ceux-ci seront-ils automatiquement créés dans le répertoire de destination dans une structure de dossiers correcte?
SexyBeast
@AttitudeMonger Non, une commande telle que cp ne crée les liens qu'une seule fois (comme vous pouvez le voir dans le résultat). Pour mettre à jour automatiquement la destination, vous devez surveiller les modifications du répertoire source.
user905686
Cela peut-il être fait pour créer des liens relatifs?
ctrl-alt-delor
@richard if SOURCE est un chemin relatif, alors je pense que oui. Essayez-le et si cela ne fonctionne pas, je vous suggère de poser une nouvelle question. Référencez celui-ci par tous les moyens.
roaima
6

Il existe au moins 2 utilitaires standard pour créer une arborescence de répertoires fantômes d'une arborescence existante, donc pas besoin d'écrire du code ici.

Il y a lndir(1)d'abord le xutils-devpaquet. Il utilise des liens symboliques vers des fichiers. Depuis la page de manuel:

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

Une alternative peut-être meilleure consiste à simplement utiliser cples bonnes options comme le suggère la réponse acceptée. Je vais juste donner quelques détails plus utiles, espérons-le:

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

Si vous ne vous souciez pas de conserver tous les attributs (propriétés / autorisations, heures), remplacez l' aoption (équivalente à -dr --preserve=all) par r(récursive uniquement):

cp -rl /src/dir /dest/dir    # hard-links to leaf-files
cp -rs /src/dir /dest/dir    # symlinks to leaf-files
arielf
la source
lndirest également disponible en tant que script shell ici au cas où il ne serait pas installé: opensource.apple.com/source/X11/X11-0.46.4/lndir.sh?txt
Lenar Hoyt
2

Vous pouvez essayer quelques commandes de recherche comme celle-ci:

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/{} \;
pichogve
la source
1

Quelque chose comme ça fera ce dont vous avez besoin.

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

Les répertoires sont créés dans l'arborescence COPY cible. Tout le reste est lié par un lien symbolique vers le chemin absolu dans l'arborescence SOURCE. Assurez-vous que SOURCE et COPY sont spécifiés en tant que chemins absolus (en commençant par /).

Si vous avez une grande arborescence à copier et que vous souhaitez un rapport d'avancement par répertoire, vous pouvez l'ajouter echo "$ITEM" >&2;juste avant la mkdircommande.

(J'ai regardé cpet cpiomais aucun ne semble avoir une option pour lier à la source avec des liens symboliques.)

roaima
la source
1
Le commentaire "test de la ligne 9" peut être lié au fait que ksh sur AIX souhaite un point-virgule pour fermer la liste entre accolades:{ mkdir -p "$COPY/$ITEM"; continue; }
Jeff Schaller
@JeffSchaller merci. Je n'ai pas écrit de kshscript ... mais il semble que ce soit également nécessaire bash. Fixation
roaima
0

S'il n'y a pas de répertoires vides dans SOURCE qui doivent être copiés

find /full/path/to/SOURCE -type f -exec cp -t COPY --parents -s {} +
mv COPY/full/path/to/SOURCE COPY
rm -r COPY/full
Costas
la source
1
Puisque vous assumez GNU de cptoute façon, pourquoi pas cp -as?
Gilles 'SO- arrête d'être méchant'
0

Je commencerais par éclater le 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::Findest un module utile qui vous permet d'exécuter un sous-programme spécifique sur n'importe quel fichier d'une arborescence de répertoires. Dans ce cas, le sous vérifie s'il s'agit d'un répertoire - et s'il l'est, fait un mkdirou un fichier - auquel cas il fait un lien symbolique.

Sobrique
la source
-1

Il semble que vous recherchiez quelque chose comme l'outil rsnapshot; il crée des copies de répertoires arbitraires et utilise des liens physiques dans la mesure du possible. (Jetez un œil à la page de manuel pour voir si cela convient.)

Janis
la source
Non, la question demande explicitement des liens symboliques et rsnapshot utilise des liens durs (car c'est un outil de sauvegarde et les fichiers doivent être conservés même s'ils sont supprimés du répertoire source).
user905686