Aqui está uma tentativa. Uma palavra de cautela: eu não testei o código a seguir extensivamente.
dirA=/path/to/dirA
dirB=/other/path/to/dirB
tmpdir=/path/to/tmpdir
cd "$dirA"
find . -type f -printf '%T@ %s %pdirA=/path/to/dirA
dirB=/other/path/to/dirB
tmpdir=/path/to/tmpdir
cd "$dirA"
find . -type f -printf '%T@ %s %p%pre%' | sort -nr -z \
awk 'BEGIN {RS="%pre%0"; ORS="%pre%0"; maxsize=2147483648}
{size += $2; if (size > maxsize) exit; print $3}' | \
rsync -Rpt --link-dest="$PWD" --files-from=- -0 . "$tmpdir" && \
rsync -rpt --delete "$tmpdir" "$dirB"
' | sort -nr -z \
awk 'BEGIN {RS="%pre%0"; ORS="%pre%0"; maxsize=2147483648}
{size += $2; if (size > maxsize) exit; print $3}' | \
rsync -Rpt --link-dest="$PWD" --files-from=- -0 . "$tmpdir" && \
rsync -rpt --delete "$tmpdir" "$dirB"
Algumas explicações:
- A finalidade das partes
find
,sort
eawk
é obter uma lista dos arquivos mais recentes, delimitada por máquina, que seja analisável por máquina, classificada pela mais nova primeiro e depois truncá-la quando o tamanho acumulado alcança 2 GiB (o 2147483648 é simplesmente 2 * 2 ^ 30 bytes, ou 2 GiB; ajuste esse número a gosto). Nota: o menor que a comparação na parteawk
significa que o tamanho é um limite superior rígido (uma condição " no máximo "), portanto, pode resultar em situações como as seguintes: se o arquivo mais recente tiver 4 GiB, nada seria incluído na sincronização. Mova oprint $3
para o início do{ }
para obter o comportamento oposto (" pelo menos "), caso em que você obteria o arquivo de 4 GiB e acabaria sincronizando duas vezes mais do que você pretendeu. Eu assumi que o primeiro era mais desejável. - O primeiro
rsync
extrai esses arquivos para um local temporário ("$tmpdir"
), mas preserva o caminho (-R
a.k.a.--relative
). Como ele usa links físicos (usando--link-dest
) e não uma cópia completa, essa etapa usa um espaço insignificante, mas$tmpdir
deve residir no mesmo sistema de arquivos que$dirA
. - A segunda invocação
rsync
faz a sincronização real com$dirB
e--delete
-ing de arquivos antigos em$dirB
não encontrados em$tmpdir
. A razão para usar o diretório temporário e fazer isso em duas etapas é que ainda não encontrei uma maneira de fazer a parte de exclusão funcionar em apenas uma etapa.