/ home/user/originalの複数のサブフォルダーに大量のPDFがあり、ghostscriptを使用して圧縮しましたpdfwritein/ home/user/compressed。
ghostscriptは、ファイルの約90%を圧縮するのに優れた仕事をしましたが、残りのファイルは元のファイルよりも大きくなりました。
cp/ home/user/compressedto/ home/user/original宛先のファイルよりものみ小さいファイルを上書きしますが、大きいファイルはスキップしました。
何か案は?
次の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"' _ {} \;
このソリューションの重要な部分は、rsync
によって提供される--max-size
です。 rsync
マニュアルから:
--max-size=SIZE
これは、指定されたSIZEより大きいファイルを転送しないようにrsyncに指示します。
したがって、find
コマンドは宛先ディレクトリ(/ home/user/original)で動作し、ファイルのリストを返します。ファイルごとに、bash
コマンドを実行するrsync
シェルを生成します。 --max-size
オプションのSIZE
パラメーターは、宛先ファイルに対してstat
コマンドを実行することによって設定されます。
事実上、rsync
処理ロジックは次のようになります。
--max-size
パラメータはソースファイルが転送されないようにします。このロジックにより、小さいファイルのみがソースディレクトリから宛先ディレクトリに転送されます。
私はこれをいくつかの異なる方法でテストしましたが、期待どおりに機能します。ただし、システムで試す前に、宛先ディレクトリのバックアップを作成することをお勧めします。
Perlの -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');