대상에서 더 작은 파일만 덮어쓰는 폴더 복사

대상에서 더 작은 파일만 덮어쓰는 폴더 복사

여러 하위 폴더에 수많은 PDF가 있습니다./홈/사용자/원본내가 사용하여 압축 한 것대본 PDF쓰기~에/홈/사용자/압축.

대본파일의 약 90%를 압축하는 데 훌륭한 작업을 수행했지만 나머지 파일은 원본보다 더 커졌습니다.

나는하고 싶다CP /홈/사용자/압축에게/홈/사용자/원본다음 파일 덮어쓰기오직대상에 있는 것보다 작은 반면 큰 것들은 건너뜁니다.

어떤 아이디어가 있나요?

답변1

find이를 위해 다음 명령이 작동해야 합니다.

cd /home/user/original
find . -type f -exec bash -c 'file="$1"; rsync --max-size=$(stat -c '%s' "$file") "/home/user/compressed/$file" "/home/user/original/$file"' _ {} \;

이 솔루션의 핵심 부분 --max-size은 에서 제공하는 것 입니다 rsync. 매뉴얼 에서 rsync:

--max-size=SIZE

이는 지정된 SIZE보다 큰 파일을 전송하지 않도록 rsync에 지시합니다.

따라서 find명령은 대상 디렉터리(/home/user/original)에서 작동하고 파일 목록을 반환합니다. 각 파일에 대해 명령을 bash실행하는 셸을 생성합니다 rsync. 옵션 매개 SIZE변수는 대상 파일에 대해 명령을 --max-size실행하여 설정됩니다 .stat

실제로 rsync처리 논리는 다음과 같습니다.

  1. 원본 파일이 대상 파일보다 큰 경우 매개 --max-size변수는 원본 파일이 전송되지 않도록 합니다.
  2. 원본 파일이 대상 파일보다 작으면 예상대로 전송이 진행됩니다.

이 논리로 인해 원본 디렉터리에서 대상 디렉터리로 더 작은 파일만 전송됩니다.

나는 이것을 몇 가지 다른 방법으로 테스트했으며 예상대로 작동했습니다. 그러나 시스템에서 시험해 보기 전에 대상 디렉터리의 백업을 생성할 수 있습니다.

답변2

펄의-에스운영자를 구출하세요!

실행 가능한 Perl 스크립트를 만듭니다 overwrite-smaller.

#!/bin/perl
use warnings;
use strict;
use File::Copy;

my $file = shift;
(my $compressed = $file) =~ s/original/compressed/;
copy($compressed, $file) if -s $compressed < -s $file;

그리고 원래 디렉터리의 각 파일에 대해 실행합니다.

find /home/user/original -type f -exec overwrite-smaller {} \;

또는 Perl에서 거기에 있는 하위 트리도 작성합니다.

#!/usr/bin/perl
use warnings;
use strict;

use File::Copy;
use File::Find;

find({no_chdir => 1,
      wanted   => sub {
          my $file = $File::Find::name;
          -f $file or return;
          (my $compressed = $file) =~ s/original/compressed/;
          copy($compressed, $file) if -s $compressed < -s $file;
    }}, 'original');

관련 정보