
Tengo toneladas de archivos PDF en varias subcarpetas en/inicio/usuario/originalque he comprimido usandoguión fantasma pdfescribiren/home/usuario/comprimido.
guión fantasmaha hecho un gran trabajo al comprimir alrededor del 90% de los archivos, sin embargo, el resto terminó siendo más grande que los originales.
Me gustaríaCP /home/usuario/comprimidoa/inicio/usuario/originalsobrescribir archivos que estánsolomás pequeños que los de destino mientras que los más grandes se omiten.
¿Algunas ideas?
Respuesta1
El siguiente find
comando debería funcionar para esto:
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"' _ {} \;
La parte clave de esta solución es la --max-size
proporcionada por rsync
. Del rsync
manual:
--max-size=SIZE
Esto le dice a rsync que evite transferir cualquier archivo que sea más grande que el TAMAÑO especificado.
Entonces el find
comando opera en el directorio de destino (/home/user/original) y devuelve una lista de archivos. Para cada archivo, genera un bash
shell que ejecuta el rsync
comando. El SIZE
parámetro de --max-size
la opción se establece ejecutando un stat
comando en el archivo de destino.
En efecto, la rsync
lógica de procesamiento pasa a ser la siguiente:
- Si el archivo de origen es más grande que el archivo de destino, el
--max-size
parámetro impedirá que se transfiera el archivo de origen. - Si el archivo de origen es más pequeño que el archivo de destino, la transferencia se realizará según lo esperado.
Esta lógica dará como resultado que solo los archivos más pequeños se transfieran desde el directorio de origen al directorio de destino.
He probado esto de diferentes maneras y funciona como se esperaba. Sin embargo, es posible que desee crear una copia de seguridad del directorio de destino antes de probarlo en su sistema.
Respuesta2
Perl-soperador al rescate!
Cree un script Perl ejecutable 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;
Y ejecútelo para cada archivo en el directorio original:
find /home/user/original -type f -exec overwrite-smaller {} \;
O, una vez en Perl, escribe el subárbol que camina allí también:
#!/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');