複製資料夾,僅覆蓋目標中較小的文件

複製資料夾,僅覆蓋目標中較小的文件

我的多個子資料夾中有大量 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');

相關內容