回答:
これにより、ジョブ全体が一度に実行されます。すべての子ディレクトリで、すべてファイル名の問題なく単一のストリームで実行されます。持っているすべてのファイルを最小から最大にコピーします。mkdir ${DESTINATION}
まだ存在しない場合は必要になります。
find . ! -type d -print0 |
du -b0 --files0-from=/dev/stdin |
sort -zk1,1n |
sed -zn 's/^[^0-9]*[0-9]*[^.]*//p' |
tar --hard-dereference --null -T /dev/stdin -cf - |
tar -C"${DESTINATION}" --same-order -xvf -
でも知ってる?これがしないのは、空の子ディレクトリです。そのパイプラインを介してリダイレクトを行うこともできますが、それはただ発生するのを待っている競合状態です。おそらく最も簡単です。したがって、後でこれを行うだけです。
find . -type d -printf 'mkdir -p "'"${DESTINATION}"'/%p"\n' |
. /dev/stdin
または、Gillesはディレクトリのアクセス許可を保持するために彼の答えで非常に良いポイントを示しているので、私も試してみるべきです。これでうまくいくと思います:
find . -type d -printf '[ -d "'"${DESTINATION}"'/%p" ] ||
cp "%p" -t "'"${DESTINATION}"'"\n' |
. /dev/stdin
mkdir
とにかくそれが速くなることに賭けたいと思います。
ここに使用する迅速で汚い方法があります rsync
です。この例では、10 MB未満のものはすべて「小さい」と考えています。
最初に小さなファイルのみを転送します。
rsync -a --max-size=10m srcdir dstdir
次に、残りのファイルを転送します。以前に転送された小さなファイルは、変更されない限り再コピーされません。
rsync -a srcdir dstdir
から man 1 rsync
--max-size=SIZE
This tells rsync to avoid transferring any file that is larger
than the specified SIZE. The SIZE value can be suffixed with a
string to indicate a size multiplier, and may be a fractional
value (e.g. "--max-size=1.5m").
This option is a transfer rule, not an exclude, so it doesn’t
affect the data that goes into the file-lists, and thus it
doesn’t affect deletions. It just limits the files that the
receiver requests to be transferred.
The suffixes are as follows: "K" (or "KiB") is a kibibyte
(1024), "M" (or "MiB") is a mebibyte (1024*1024), and "G" (or
"GiB") is a gibibyte (1024*1024*1024). If you want the multi‐
plier to be 1000 instead of 1024, use "KB", "MB", or "GB".
(Note: lower-case is also accepted for all values.) Finally, if
the suffix ends in either "+1" or "-1", the value will be offset
by one byte in the indicated direction.
Examples: --max-size=1.5mb-1 is 1499999 bytes, and
--max-size=2g+1 is 2147483649 bytes.
もちろん、ファイルごとの転送の順序は厳密には最小から最大ではありませんが、要件の精神を満たす最も簡単なソリューションであると思います。
--copy-dest=DIR
と/または--compare-dest=DIR
私は思います。リンクが見つからなかったため、自分の回答を投稿--hard-dereference
したtar
後に自分を追加しなければならなかった原因しかわかりません。rsync
とにかく、実際には他のユーザーとのローカルファイルシステムにより固有の動作をしていると思います。以前はUSBキーで使用していたため、帯域幅の制限を設定しない限り、バスがあふれます。代わりに他のいずれかを使用すべきだったと思います。
ないcp
直接、それは十分にその能力を超えています。ただしcp
、正しい順序でファイルを呼び出すように手配できます。
Zshでは、glob修飾子を使用して、サイズでファイルを簡単にソートできます。以下は、サイズの昇順でファイル/path/to/source-directory
をunder からunder にコピーするzshスニペット/path/to/destination-directory
です。
cd /path/to/source-directory
for x in **/*(.oL); do
mkdir -p /path/to/destination-directory/$x:h
cp $x /path/to/destination-directory/$x:h
done
ループの代わりに、zcp
関数を使用できます。ただし、最初に宛先ディレクトリを作成する必要があります。これは、暗号化されたワンライナーで実行できます。
autoload -U zmv; alias zcp='zmv -C'
cd /path/to/source-directory
mkdir **/*(/e\''REPLY=/path/to/destination-directory/$REPLY'\')
zcp -Q '**/*(.oL)' '/path/to/destination-directory/$f'
これは、ソースディレクトリの所有権を保持しません。必要な場合は、cpio
またはなどの適切なコピープログラムを登録する必要がありますpax
。あなたがそれを行う場合は、呼び出す必要はありませんcp
か、zcp
加えて。
cd /path/to/source-directory
print -rN **/*(^.) **/*(.oL) | cpio -0 -p /path/to/destination-directory
cp -r
これを直接行う方法はないと思います。ウィザードfind
/ awk
ソリューションを得るまでの期間は不定かもしれないので、ここに簡単なperlスクリプトがあります:
#!/usr/bin/perl
use strict;
use warnings FATAL => qw(all);
use File::Find;
use File::Basename;
die "No (valid) source directory path given.\n"
if (!$ARGV[0] || !-d -r "/$ARGV[0]");
die "No (valid) destination directory path given.\n"
if (!$ARGV[1] || !-d -w "/$ARGV[1]");
my $len = length($ARGV[0]);
my @files;
find (
sub {
my $fpath = $File::Find::name;
return if !-r -f $fpath;
push @files, [
substr($fpath, $len),
(stat($fpath))[7],
]
}, $ARGV[0]
);
foreach (sort { $a->[1] <=> $b->[1] } @files) {
if ($ARGV[2]) {
print "$_->[1] $ARGV[0]/$_->[0] -> $ARGV[1]/$_->[0]\n";
} else {
my $dest = "$ARGV[1]/$_->[0]";
my $dir = dirname($dest);
mkdir $dir if !-e $dir;
`cp -a "$ARGV[0]/$_->[0]" $dest`;
}
}
これを使って: ./whatever.pl /src/path /dest/path
引数は両方とも絶対パスでなければなりません。~
、またはシェルが絶対パスに展開する他のものは問題ありません。
3番目の引数(リテラル以外の任意のもの0
)を追加すると、コピーする代わりに、ファイルのサイズがバイト単位で追加された状態で、レポートの出力が標準出力に出力されます。
4523 /src/path/file.x -> /dest/path/file.x
12124 /src/path/file.z -> /dest/path/file.z
これらはサイズの昇順であることに注意してください。
cp
34行目のコマンドはリテラルシェルコマンドであるため、スイッチを使用-a
して任意の操作を実行できます(すべての特性を保持するために使用しました)。
File::Find
そしてFile::Basename
、両方のコアモジュールです彼らはperlののすべてのインストールで使用できますすなわち。
cp - copy smallest files first?
、投稿のタイトルはcopy smallest files first?
とにかく、オプションは決して傷つけることはありませんが、それでも、あなたとデビッドが使用した唯一のものでcp
あり、あなただけがそれを引き出しました。
cp
た唯一の理由は、それが(クロスプラットフォーム指向の)perlで* nixファイルの特性を保持する最も簡単な方法だからです。ブラウザバーに表示される理由cp -
は、選択したタグの中で最も人気のあるタグが実際のタイトルの前に表示される(IMO間抜けな)SE機能のためです。
pearl
、この辺りの木工から出てくるのを見ることはあまりありません。
別のオプションは、duからの出力でcpを使用することです。
oldIFS=$IFS
IFS=''
for i in $(du -sk *mpg | sort -n | cut -f 2)
do
cp $i destination
done
IFS=$oldIFS
これはまだ1行で行うことができますが、あなたが読むことができるように私はそれを分割します