Wie kopiere ich eine Ordnerstruktur und knüpfe symbolische Links zu Dateien?


21

Ich habe einen Ordner SOURCE, der mehrere Unterordner mit jeweils eigenen Dateien enthält.

Ich möchte diesen Ordner in einen neuen Ordner COPY kopieren, wo ich die Verzeichnisstruktur kopieren muss, aber die Dateien als symbolische Links zu den Originaldateien in SOURCE und seinen Unterordnern behalte.



GNU Stow macht das irgendwie.
Kusalananda

Antworten:


27

Hier ist die Lösung für nicht eingebettetes Linux und Cygwin:

cp -as SOURCE/ COPY

Beachten Sie, dass SOURCE ein absoluter Pfad und ein abschließender Schrägstrich sein muss. Wenn Sie einen relativen Pfad angeben möchten, können Sie verwenden

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

Funktioniert perfekt, danke. Nur eine Anmerkung .. SOURCE muss mit vollem Pfad angegeben werden (COPY kann stattdessen in relativen Begriffen angegeben werden, wenn man es wünscht)
Antonello

Wie funktioniert es, wenn das Quellverzeichnis ständig mit neuen Ordnern und neuen Dateien aktualisiert wird? Werden Symlinks zu ihnen automatisch im Zielverzeichnis in der richtigen Ordnerstruktur erstellt?
SexyBeast

@AttitudeMonger Nein, ein Befehl wie cp erstellt die Links nur einmal (wie Sie aus dem Ergebnis ersehen können). Um das Ziel automatisch zu aktualisieren, müssten Sie das Quellverzeichnis auf Änderungen überwachen.
User905686

Kann dies getan werden, um relative Links zu erstellen?
Strg-Alt-Delor

@richard wenn SOURCE das ein relativer weg ist dann denke ich schon. Probieren Sie es aus, und wenn dies nicht funktioniert, möchten Sie möglicherweise eine neue Frage stellen. Verweisen Sie auf jeden Fall auf diese.
Roaima

6

Es gibt mindestens 2 Standarddienstprogramme zum Erstellen eines Schattenverzeichnisbaums eines vorhandenen Baums, sodass hier kein Code geschrieben werden muss.

Zuerst gibt es lndir(1)aus dem xutils-devPaket. Es werden Symlinks zu Dateien verwendet. Von der Manpage:

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

Eine vielleicht bessere Alternative ist es, einfach cpmit den richtigen Optionen zu arbeiten, wie die akzeptierte Antwort nahelegt. Ich gebe nur ein paar hoffentlich nützliche Details:

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

Wenn Sie nicht alle Attribute (Eigentumsrechte / Berechtigungen, Zeiten) beibehalten möchten, ersetzen Sie die aOption (äquivalent zu -dr --preserve=all) durch r(nur rekursiv):

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

lndirist auch als Shell-Skript hier verfügbar, falls es nicht installiert ist: opensource.apple.com/source/X11/X11-0.46.4/lndir.sh?txt
Lenar Hoyt

2

Sie können einige Suchbefehle wie diesen ausprobieren:

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

So etwas wird tun, was Sie brauchen.

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

Verzeichnisse werden im Ziel-COPY-Baum erstellt. Alles andere ist mit dem absoluten Pfad innerhalb des SOURCE-Baums verknüpft. Stellen Sie sicher, dass sowohl SOURCE als auch COPY als absolute Pfade angegeben sind (beginnend mit /).

Wenn Sie einen großen Baum zum Kopieren haben und einen Pro-Verzeichnis-Fortschrittsbericht möchten, können Sie ihn echo "$ITEM" >&2;direkt vor dem mkdirBefehl hinzufügen .

(Ich habe mir das angeschaut cpund cpioes scheint auch keine Möglichkeit zu geben, mit symbolischen Links auf die Quelle zu verlinken.)


1
Der Kommentar "Test in Zeile 9" bezieht sich möglicherweise auf ksh unter AIX, bei dem ein Semikolon die in geschweifte Klammern eingeschlossene Liste schließen soll:{ mkdir -p "$COPY/$ITEM"; continue; }
Jeff Schaller

@ JeffSchaller danke. Ich habe kein kshDrehbuch geschrieben ... aber es sieht so aus, als ob das auch notwendig ist bash. Fixing
Roaima

0

Wenn in SOURCE keine leeren Verzeichnisse vorhanden sind, die kopiert werden müssen

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
Da Sie cpsowieso von GNU ausgehen , warum nicht cp -as?
Gilles 'SO- hör auf böse zu sein'

0

Ich würde damit beginnen, das Perl auszubrechen:

#!/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::Findist ein nützliches Modul, mit dem Sie eine bestimmte Unterroutine für eine beliebige Datei in einem Verzeichnisbaum ausführen können. In diesem Fall prüft das Sub, ob es sich um ein Verzeichnis handelt - und wenn ja, um eine mkdiroder eine Datei. In diesem Fall führt es einen Symlink durch.


-1

Es scheint, dass Sie nach etwas wie dem Werkzeug suchen rsnapshot; Es werden Kopien beliebiger Verzeichnisse erstellt und wenn möglich Hardlinks verwendet. (Sehen Sie in der Manpage nach, ob das passt.)


Nein, die Frage fragt explizit nach Symlinks und rsnapshot verwendet Hardlinks (da es sich um ein Sicherungswerkzeug handelt und die Dateien auch dann aufbewahrt werden sollten, wenn sie aus dem Quellverzeichnis entfernt werden).
User905686
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.