Sim, isso é possível.
Uma solução /bin/sh
:
#!/bin/sh
# number of entries to sync
k=2
# generate file list (sets $1, $2, $3 etc., collectively known as $@)
set -- src/*
# shift off all but the last $k of these entries
shift "$(( $# - k ))"
# create include patterns ($entry is not actually used,
# we work on the 1st element and then add it to the end and shift)
for entry do
set -- "$@" --include="${1##*/}/***"
shift
done
# run rsync
rsync --verbose --archive --delete --delete-excluded "$@" --exclude='*' src/ dest/
Isso cria uma lista de arquivos em $@
com set
primeiro (essa lista é classificada lexicograficamente, porque globs faz isso) e, em seguida, remove todos, exceto o último $k
desses arquivos. O loop converte cada src/element
em --include=element/***
. Esse padrão de inclusão fará com que rsync
considere o nome element
e qualquer coisa abaixo dele. Esses padrões de inclusão são usados na linha de comando rsync
juntamente com --exclude='*'
, o que excluirá tudo que não estiver explicitamente incluído (a primeira correspondência é importante).
A rsync
run usa --delete
, que excluirá qualquer coisa dos subdiretórios incluídos no destino que não estiver disponível no diretório de origem, e --delete-excluded
excluirá também tudo que foi excluído.
Execute o script com sh -x
para ver o que acontece.
Você também pode fazer isso em bash
com arrays, mas a sintaxe é um pouco confusa.