复制文件夹,仅覆盖目标中较小的文件

复制文件夹,仅覆盖目标中较小的文件

我的多个子文件夹中有大量 PDF 文件/home/用户/原始我已经使用压缩鬼脚本 pdf写入/home/用户/压缩

鬼脚本在压缩大约 90% 的文件方面做得很好,但其余文件最终比原始文件大。

我想CP /home/用户/压缩/home/用户/原始覆盖文件仅有的小于目的地的,而较大的被跳过。

有任何想法吗?

答案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由 提供的rsync。从rsync手册:

--max-size=SIZE

这告诉 rsync 避免传输任何大于指定 SIZE 的文件。

因此该find命令对目标目录(/home/user/original)进行操作并返回文件列表。对于每个文件,它都会生成一个bash运行rsync命令的 shell。选项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');

相关内容