Para criar uma lista de arquivos novos ou modificados programaticamente, a melhor solução que posso usar é usar rsync , classificar e uniq :
(rsync -rcn --out-format="%n" old/ new/ && rsync -rcn --out-format="%n" new/ old/) | sort | uniq
Deixe-me explicar com este exemplo: queremos comparar duas versões dokuwiki para ver quais arquivos foram alterados e quais foram criados recentemente.
Nós buscamos os tars com wget e os extraímos nos diretórios old/
e new/
:
wget http://download.dokuwiki.org/src/dokuwiki/dokuwiki-2014-09-29d.tgz
wget http://download.dokuwiki.org/src/dokuwiki/dokuwiki-2014-09-29.tgz
mkdir old && tar xzf dokuwiki-2014-09-29.tgz -C old --strip-components=1
mkdir new && tar xzf dokuwiki-2014-09-29d.tgz -C new --strip-components=1
A execução do rsync de uma maneira pode perder arquivos recém-criados, como mostra a comparação do rsync e diff aqui:
rsync -rcn --out-format="%n" old/ new/
produz o seguinte resultado:
VERSION
doku.php
conf/mime.conf
inc/auth.php
inc/lang/no/lang.php
lib/plugins/acl/remote.php
lib/plugins/authplain/auth.php
lib/plugins/usermanager/admin.php
Rodar o rsync somente em uma direção erra os arquivos recém-criados e o inverso perderia arquivos deletados, compare a saída do diff:
diff -qr old/ new/
produz o seguinte resultado:
Files old/VERSION and new/VERSION differ
Files old/conf/mime.conf and new/conf/mime.conf differ
Only in new/data/pages: playground
Files old/doku.php and new/doku.php differ
Files old/inc/auth.php and new/inc/auth.php differ
Files old/inc/lang/no/lang.php and new/inc/lang/no/lang.php differ
Files old/lib/plugins/acl/remote.php and new/lib/plugins/acl/remote.php differ
Files old/lib/plugins/authplain/auth.php and new/lib/plugins/authplain/auth.php differ
Files old/lib/plugins/usermanager/admin.php and new/lib/plugins/usermanager/admin.php differ
Executar rsync nos dois sentidos e classificar a saída para remover duplicatas revela que o diretório data/pages/playground/
e o arquivo data/pages/playground/playground.txt
foram perdidos inicialmente:
(rsync -rcn --out-format="%n" old/ new/ && rsync -rcn --out-format="%n" new/ old/) | sort | uniq
produz o seguinte resultado:
VERSION
conf/mime.conf
data/pages/playground/
data/pages/playground/playground.txt
doku.php
inc/auth.php
inc/lang/no/lang.php
lib/plugins/acl/remote.php
lib/plugins/authplain/auth.php
lib/plugins/usermanager/admin.php
rsync
é executado com esses argumentos:
-
-r
para "recursionar em diretórios",
-
-c
para comparar também arquivos de tamanho idêntico e apenas "pular com base na soma de verificação, não no tamanho e tamanho da modalidade",
-
-n
para "executar uma avaliação sem alterações" e
-
--out-format="%n"
para "enviar atualizações usando o FORMATO especificado", que é "% n" aqui apenas para o nome do arquivo
A saída (lista de arquivos) de rsync
em ambas as direções é combinada e classificada usando sort
, e essa lista classificada é condensada removendo todos os duplicados com uniq