ฉันมีโฟลเดอร์ SOURCE ที่มีโฟลเดอร์ย่อยหลายโฟลเดอร์โดยแต่ละไฟล์มีไฟล์ของตัวเอง
ฉันต้องการคัดลอกโฟลเดอร์นี้ในโฟลเดอร์ใหม่คัดลอกที่ฉันต้องการคัดลอกโครงสร้างไดเรกทอรี แต่เก็บไฟล์เป็นลิงก์สัญลักษณ์ไปยังไฟล์ต้นฉบับใน SOURCE และโฟลเดอร์ย่อย
ฉันมีโฟลเดอร์ SOURCE ที่มีโฟลเดอร์ย่อยหลายโฟลเดอร์โดยแต่ละไฟล์มีไฟล์ของตัวเอง
ฉันต้องการคัดลอกโฟลเดอร์นี้ในโฟลเดอร์ใหม่คัดลอกที่ฉันต้องการคัดลอกโครงสร้างไดเรกทอรี แต่เก็บไฟล์เป็นลิงก์สัญลักษณ์ไปยังไฟล์ต้นฉบับใน SOURCE และโฟลเดอร์ย่อย
คำตอบ:
นี่คือวิธีการแก้ปัญหาบน Linux และ Cygwin ที่ไม่ใช่แบบฝังตัว:
cp -as SOURCE/ COPY
โปรดทราบว่าแหล่งที่มาจะต้องเป็นเส้นทางที่แน่นอนและมีเครื่องหมายทับ หากคุณต้องการให้เส้นทางสัมพัทธ์คุณสามารถใช้
cp -as "$(pwd)/SOURCE/" COPY
SOURCE
เป็นเส้นทางญาติแล้วฉันคิดอย่างนั้น ลองใช้และหากวิธีนี้ใช้ไม่ได้ฉันขอแนะนำให้คุณอาจต้องการถามคำถามใหม่ อ้างอิงอันนี้ทุกวิถีทาง
มียูทิลิตี้มาตรฐานอย่างน้อย 2 ตัวในการสร้างแผนผังไดเรกทอรีเงาของต้นไม้ที่มีอยู่ดังนั้นไม่จำเป็นต้องเขียนโค้ดที่นี่
ก่อนอื่นlndir(1)
มาจากxutils-dev
แพ็คเกจ มันใช้ symlink กับไฟล์ จากหน้าคน:
NAME
lndir - create a shadow directory of symbolic links to another
directory tree
SYNOPSIS
lndir [ -silent ] [ -ignorelinks ] [ -withrevinfo ] fromdir [ todir ]
ทางเลือกที่ดีกว่าอาจจะใช้cp
กับตัวเลือกที่เหมาะสมตามคำตอบที่ได้รับการยอมรับ ฉันจะให้รายละเอียดที่เป็นประโยชน์เพิ่มเติมหวังว่า:
cp -al /src/dir /dest/dir # hard-links to leaf-files
cp -as /src/dir /dest/dir # symlinks to leaf-files
หากคุณไม่สนใจเกี่ยวกับการรักษาคุณลักษณะทั้งหมด (ความเป็นเจ้าของ / สิทธิ์ครั้ง) ให้แทนที่a
ตัวเลือก (เทียบเท่า-dr --preserve=all
) ด้วยr
(เรียกซ้ำเท่านั้น):
cp -rl /src/dir /dest/dir # hard-links to leaf-files
cp -rs /src/dir /dest/dir # symlinks to leaf-files
lndir
มีให้ใช้งานเป็นสคริปต์เชลล์ที่นี่ในกรณีที่ไม่ได้ติดตั้ง: opensource.apple.com/source/X11/X11-0.46.4/lndir.sh?txt
คุณสามารถลองใช้คำสั่ง find สองสามแบบดังนี้:
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/{} \;
สิ่งนี้จะทำในสิ่งที่คุณต้องการ
#!/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
ไดเรกทอรีถูกสร้างขึ้นในแผนผัง COPY เป้าหมาย ทุกสิ่งทุกอย่างจะเชื่อมโยงกลับไปยังเส้นทางที่สมบูรณ์ภายในทรี SOURCE ตรวจสอบให้แน่ใจว่าทั้งแหล่งที่มาและสำเนาถูกระบุเป็นพา ธ สัมบูรณ์ (เริ่มต้นด้วย/
)
หากคุณมีต้นไม้ขนาดใหญ่ที่จะคัดลอกและคุณต้องการรายงานความคืบหน้าต่อไดเรกทอรีคุณสามารถเพิ่มecho "$ITEM" >&2;
ก่อนmkdir
คำสั่ง
(ฉันดูcp
แล้วcpio
แต่ดูเหมือนจะไม่มีตัวเลือกสำหรับการลิงก์ไปยังแหล่งที่มาพร้อมกับลิงก์สัญลักษณ์)
{ mkdir -p "$COPY/$ITEM"; continue; }
ksh
สคริปต์ ... แต่ดูเหมือนว่ามันก็จำเป็นbash
เช่นกัน แก้ไข
หากไม่มี dirs ที่ว่างเปล่าใน SOURCE ซึ่งจำเป็นต้องคัดลอก
find /full/path/to/SOURCE -type f -exec cp -t COPY --parents -s {} +
mv COPY/full/path/to/SOURCE COPY
rm -r COPY/full
cp
อยู่แล้วทำไมcp -as
ล่ะ
ฉันจะเริ่มต้นด้วยการทำลาย 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
เป็นโมดูลที่มีประโยชน์ที่อนุญาตให้คุณเรียกใช้รูทีนย่อยเฉพาะบนไฟล์ใด ๆ ภายในแผนผังไดเร็กทอรี ในกรณีนี้ส่วนย่อยจะตรวจสอบว่าเป็นไดเรกทอรีmkdir
หรือไม่และเป็นไฟล์หรือไม่ซึ่งในกรณีนี้ symlink
ดูเหมือนว่าคุณกำลังมองหาบางสิ่งบางอย่างเช่นเครื่องมือrsnapshot
; มันสร้างสำเนาของไดเรกทอรีที่กำหนดเองและใช้ฮาร์ดลิงก์เมื่อทำได้ (ดูที่หน้า man page เพื่อดูว่าเหมาะสมหรือไม่)