
Ich habe jede Menge PDFs in mehreren Unterordnern in/home/Benutzer/originaldie ich komprimiert habe mitGhostscript pdfschreibenIn/home/Benutzer/komprimiert.
Ghostscripthat gute Arbeit geleistet und etwa 90 % der Dateien komprimiert, der Rest war jedoch größer als die Originale.
Ich möchtecp /home/Benutzer/komprimiertZu/home/Benutzer/originalÜberschreiben von Dateien, dienurkleiner als die im Ziel, während die größeren übersprungen werden.
Irgendwelche Ideen?
Antwort1
Der folgende find
Befehl sollte hierfür funktionieren:
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"' _ {} \;
Der Schlüsselteil dieser Lösung wird --max-size
bereitgestellt von rsync
. Aus dem rsync
Handbuch:
--max-size=SIZE
Dadurch wird rsync angewiesen, die Übertragung von Dateien zu vermeiden, die größer als die angegebene GRÖSSE sind.
Der find
Befehl arbeitet also im Zielverzeichnis (/home/user/original) und gibt eine Liste von Dateien zurück. Für jede Datei wird eine bash
Shell gestartet, die den rsync
Befehl ausführt. Der SIZE
Parameter für --max-size
die Option wird festgelegt, indem ein stat
Befehl für die Zieldatei ausgeführt wird.
Tatsächlich rsync
sieht die Verarbeitungslogik folgendermaßen aus:
- Wenn die Quelldatei größer als die Zieldatei ist,
--max-size
verhindert der Parameter die Übertragung der Quelldatei. - Wenn die Quelldatei kleiner als die Zieldatei ist, wird die Übertragung wie erwartet fortgesetzt.
Diese Logik führt dazu, dass nur die kleineren Dateien vom Quellverzeichnis in das Zielverzeichnis übertragen werden.
Ich habe dies auf verschiedene Arten getestet und es funktioniert bei mir wie erwartet. Sie sollten jedoch möglicherweise eine Sicherungskopie des Zielverzeichnisses erstellen, bevor Sie es auf Ihrem System ausprobieren.
Antwort2
Perls-SBetreiber zur Rettung!
Erstellen Sie ein ausführbares Perl-Skript 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;
Und führen Sie es für jede Datei im Originalverzeichnis aus:
find /home/user/original -type f -exec overwrite-smaller {} \;
Oder schreiben Sie in Perl auch den Teilbaum, der dorthin führt:
#!/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');