フォルダをコピーして、ターゲットの小さなファイルのみを上書きします。

フォルダをコピーして、ターゲットの小さなファイルのみを上書きします。

複数のサブフォルダに多数の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はで提供されていますrsyncrsyncマニュアルから:

--max-size=SIZE

これは、指定されたサイズより大きいファイルを転送しないようにrsyncに指示します。

したがって、このfindコマンドはターゲットディレクトリ(/home/user/original)で動作し、ファイルのリストを返します。各ファイルに対してコマンドをbash実行するシェルを作成します。rsyncオプションSIZEパラメータは、ターゲットファイルでコマンドを実行して--max-size設定statされます。

実際、rsync処理ロジックは次のようになります。

  1. このパラメータは、ソースファイルがターゲットファイルより大きい場合にソース --max-sizeファイルが転送されるのを防ぎます。
  2. ソースファイルがターゲットファイルより小さい場合、転送は期待どおりに機能します。

このロジックを使用すると、小さいファイルだけがソースディレクトリから宛先ディレクトリに転送されます。

私はこれをいくつかの異なる方法でテストし、期待通りに動作しました。ただし、システムが試す前に、ターゲットディレクトリのバックアップを作成できます。

答え2

真珠-Sオペレーターが救助に来ます!

実行可能な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');

関連情報