
Tenho toneladas de PDFs em várias subpastas em/home/usuário/originalque eu compactei usandoscript fantasma pdfwriteem/home/usuário/comprimido.
script fantasmafez um ótimo trabalho ao compactar cerca de 90% dos arquivos, porém o restante deles acabou maior que os originais.
Eu gostaria deCP /home/usuário/comprimidopara/home/usuário/originalsobrescrevendo arquivos que sãoapenasmenores que os do destino, enquanto os maiores são ignorados.
Alguma ideia?
Responder1
O seguinte find
comando deve funcionar para isso:
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"' _ {} \;
A parte principal desta solução é --max-size
fornecida pelo rsync
. Do rsync
manual:
--max-size=SIZE
Isso diz ao rsync para evitar a transferência de qualquer arquivo maior que o SIZE especificado.
Portanto, o find
comando opera no diretório de destino (/home/user/original) e retorna uma lista de arquivos. Para cada arquivo, ele gera um bash
shell que executa o rsync
comando. O SIZE
parâmetro para --max-size
opção é definido executando um stat
comando no arquivo de destino.
Com efeito, a rsync
lógica de processamento torna-se esta:
- Se o arquivo de origem for maior que o arquivo de destino, o
--max-size
parâmetro impedirá que o arquivo de origem seja transferido. - Se o arquivo de origem for menor que o arquivo de destino, a transferência prosseguirá conforme o esperado.
Essa lógica resultará na transferência apenas dos arquivos menores do diretório de origem para o diretório de destino.
Eu testei isso de algumas maneiras diferentes e funciona para mim conforme esperado. No entanto, você pode querer criar um backup do diretório de destino antes de testá-lo em seu sistema.
Responder2
Perl-soperador para o resgate!
Crie um script Perl executável 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;
E execute-o para cada arquivo no diretório original:
find /home/user/original -type f -exec overwrite-smaller {} \;
Ou, uma vez em Perl, escreva a subárvore que caminha até lá também:
#!/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');