Làm cách nào để sao chép cấu trúc thư mục và tạo liên kết tượng trưng đến các tệp?


21

Tôi có một thư mục SOURCE chứa một số thư mục cấp phụ, mỗi thư mục có các tệp riêng.

Tôi muốn sao chép thư mục này trong một thư mục mới SAO CHÉP trong đó tôi cần sao chép cấu trúc thư mục nhưng giữ các tệp dưới dạng liên kết tượng trưng đến các tệp gốc trong SOURCE và các thư mục con của nó.



GNU Stow kinda làm điều này.
Kusalananda

Câu trả lời:


27

Đây là giải pháp trên Linux và Cygwin không nhúng:

cp -as SOURCE/ COPY

Lưu ý rằng NGUỒN phải là một đường dẫn tuyệt đối và có dấu gạch chéo. Nếu bạn muốn đưa ra một đường dẫn tương đối, bạn có thể sử dụng

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

Hoạt động hoàn hảo, cảm ơn bạn. Chỉ cần một lưu ý .. NGUỒN phải được cung cấp với đường dẫn đầy đủ (thay vào đó, COPY có thể được cung cấp theo thuật ngữ tương đối nếu muốn)
Antonello

Làm thế nào để làm cho nó hoạt động nếu thư mục nguồn sẽ được cập nhật liên tục với các thư mục mới và các tệp mới bên trong chúng? Các liên kết tượng trưng cho chúng sẽ được tạo tự động trong thư mục đích trong cấu trúc thư mục chính xác?
SexyBeast

@AttitudeMonger Không, một lệnh như cp chỉ tạo các liên kết một lần (như bạn có thể thấy từ kết quả). Để tự động cập nhật đích, bạn sẽ phải theo dõi thư mục nguồn để thay đổi.
dùng905686

Điều này có thể được thực hiện để tạo liên kết tương đối?
ctrl-alt-delor

@richard nếu SOURCE là một con đường tương đối thì tôi nghĩ vậy. Hãy thử nó và nếu điều này không hiệu quả, tôi đề nghị bạn có thể muốn hỏi một câu hỏi mới. Tham khảo cái này bằng mọi cách.
roaima

6

Có ít nhất 2 tiện ích tiêu chuẩn để xây dựng cây thư mục bóng của cây hiện có, vì vậy không cần phải viết mã ở đây.

Đầu tiên là lndir(1)từ xutils-devgói. Nó sử dụng symlink đến tập tin. Từ trang người đàn ông:

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

Một sự thay thế có lẽ tốt hơn là chỉ cần sử dụng cpvới các tùy chọn đúng như câu trả lời được chấp nhận cho thấy. Tôi sẽ chỉ cung cấp thêm một số chi tiết hữu ích hy vọng:

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

Nếu bạn không quan tâm đến việc giữ tất cả các thuộc tính (quyền sở hữu / quyền, thời gian) thay thế atùy chọn (tương đương -dr --preserve=all) bằng r(chỉ đệ quy):

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

lndircũng có sẵn dưới dạng tập lệnh shell ở đây trong trường hợp chưa được cài đặt: opensource.apple.com/source/X11/X11-0.46.4/lndir.sh?txt
Lenar Hoyt

2

Bạn có thể thử một vài lệnh tìm như thế này:

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

Một cái gì đó như thế này sẽ làm những gì bạn cần.

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

Các thư mục được tạo trong cây COPY đích. Mọi thứ khác được liên kết trở lại đường dẫn tuyệt đối trong cây SOURCE. Đảm bảo rằng cả SOURCE và COPY đều được chỉ định là đường dẫn tuyệt đối (bắt đầu bằng /).

Nếu bạn có một cây lớn để sao chép và bạn muốn báo cáo tiến trình theo từng thư mục, bạn có thể thêm echo "$ITEM" >&2;ngay trước mkdirlệnh.

(Tôi đã xem cpcpiodường như không có tùy chọn nào để liên kết với nguồn bằng các liên kết tượng trưng.)


1
Nhận xét "kiểm tra dòng 9" có thể có liên quan đến ksh trên AIX muốn có dấu chấm phẩy để đóng danh sách kèm theo dấu ngoặc kép:{ mkdir -p "$COPY/$ITEM"; continue; }
Jeff Schaller

@JeffSchaller cảm ơn. Tôi đã không viết một kshkịch bản ... nhưng có vẻ như điều đó cũng cần thiết bash. Sửa lỗi
roaima

0

Nếu không có thư mục trống trong SOURCE cần được sao chép

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
cpdù sao bạn cũng đang giả sử GNU , tại sao không cp -as?
Gilles 'SO- ngừng trở nên xấu xa'

0

Tôi sẽ bắt đầu bằng cách thoát ra khỏi 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::Findlà một mô-đun hữu ích cho phép bạn chạy một chương trình con cụ thể trên bất kỳ tệp nào trong cây thư mục. Trong trường hợp này, phụ kiểm tra xem đó có phải là một thư mục không - và nếu có, thì nó có phải là mkdirmột tập tin hay không - trong trường hợp đó là một liên kết tượng trưng.


-1

Có vẻ như bạn đang tìm kiếm một cái gì đó giống như công cụ rsnapshot; nó tạo ra các bản sao của các thư mục tùy ý và sử dụng các liên kết cứng nếu có thể. (Hãy xem trang người đàn ông để xem có phù hợp không.)


Không, câu hỏi yêu cầu rõ ràng về symlink và rsnapshot sử dụng liên kết cứng (vì đây là công cụ sao lưu và các tệp nên được giữ ngay cả khi chúng bị xóa khỏi thư mục nguồn).
dùng905686
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.