답변:
이것은 모든 하위 디렉토리에서 파일 이름 문제없이 단일 스트림으로 전체 작업을 한 번에 수행합니다. 모든 파일을 최소에서 최대로 복사합니다. 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
. 이 예제에서는 10MB 미만의 것을 "작은"것으로 간주합니다.
먼저 작은 파일 만 전송하십시오.
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
로 크기가 커지는 파일을 복사하는 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
함수를 사용할 수 있습니다 . 그러나 대상 디렉토리를 먼저 작성해야하며 이는 암호화 된 oneliner에서 수행 할 수 있습니다.
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
솔루션 을 얻기까지는 시간이 불확실 할 수 있으므로 다음과 같은 간단한 펄 스크립트가 있습니다 :
#!/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
인수는 모두 절대 경로 여야합니다 . ~
또는 쉘이 절대 경로로 확장되는 다른 모든 것이 좋습니다.
세 번째 인수 (리터럴 제외)를 추가하면 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
, 두 핵심 모듈이다 그들은 펄의 모든 설치에서 사용할 수 있습니다 즉.
cp - copy smallest files first?
되었지만 게시물의 제목은 copy smallest files first?
어쨌든 옵션은 결코 내 철학이 아닙니다. 그러나 여전히 당신과 David는 사용 된 유일한 사람 cp
이며 당신은 그것을 뽑아 낸 유일한 사람입니다.
cp
는 (크로스 플랫폼 지향) perl에서 * nix 파일 특성을 유지하는 가장 간단한 방법이기 때문입니다. 브라우저 표시 줄에 표시되는 이유 cp -
는 (IMO goofy) 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
이것은 여전히 한 줄로 할 수는 있지만 읽을 수 있도록 분할했습니다.