私はいくつかのサブレベルのフォルダーを含むフォルダーSOURCEを持ち、それぞれに独自のファイルがあります。
このフォルダーを新しいフォルダーCOPYにコピーしたいのですが、ディレクトリ構造をコピーする必要がありますが、ファイルをSOURCEとそのサブフォルダーの元のファイルへのシンボリックリンクとして保持します。
組み込みでないLinuxとCygwinでのソリューションは次のとおりです。
cp -as SOURCE/ COPY
SOURCEは絶対パスである必要があり、末尾にスラッシュが必要です。相対パスを指定したい場合は、
cp -as "$(pwd)/SOURCE/" COPY
既存のツリーのシャドウディレクトリツリーを構築するための少なくとも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
_
次のような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ツリー内の絶対パスにシンボリックリンクされます。 SOURCEとCOPYの両方が絶対パスとして指定されていることを確認してください(/
で始まる)。
コピーする大きなツリーがあり、ディレクトリごとの進捗レポートが必要な場合は、mkdir
コマンドの直前にecho "$ITEM" >&2;
を追加できます。
(cp
とcpio
を調べましたが、どちらにもシンボリックリンクでソースにリンクするオプションがないようです。)
コピーする必要がある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
私は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
またはファイルを実行します。この場合、シンボリックリンクを実行します。