web-dev-qa-db-ja.com

フォルダー構造をコピーしてファイルへのシンボリックリンクを作成する方法

私はいくつかのサブレベルのフォルダーを含むフォルダーSOURCEを持ち、それぞれに独自のファイルがあります。

このフォルダーを新しいフォルダーCOPYにコピーしたいのですが、ディレクトリ構造をコピーする必要がありますが、ファイルをSOURCEとそのサブフォルダーの元のファイルへのシンボリックリンクとして保持します。

22
Antonello

組み込みでないLinuxとCygwinでのソリューションは次のとおりです。

cp -as SOURCE/ COPY

SOURCEは絶対パスである必要があり、末尾にスラッシュが必要です。相対パスを指定したい場合は、

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

既存のツリーのシャドウディレクトリツリーを構築するための少なくとも2つの標準ユーティリティがあるため、ここにコードを記述する必要はありません。

まず、_xutils-dev_パッケージのlndir(1)があります。ファイルへのシンボリックリンクを使用します。 manページから:

_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
_
8
arielf

次のような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/{} \;
2
pichogve

このような何かがあなたが必要とすることをします。

#!/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ツリー内の絶対パスにシンボリックリンクされます。 SOURCEとCOPYの両方が絶対パスとして指定されていることを確認してください(/で始まる)。

コピーする大きなツリーがあり、ディレクトリごとの進捗レポートが必要な場合は、mkdirコマンドの直前にecho "$ITEM" >&2;を追加できます。

cpcpioを調べましたが、どちらにもシンボリックリンクでソースにリンクするオプションがないようです。)

1
roaima

コピーする必要がある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
0
Costas

私は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またはファイルを実行します。この場合、シンボリックリンクを実行します。

0
Sobrique