Para criar uma lista de arquivos novos ou modificados de forma programática, a melhor solução que eu poderia encontrar é usar rsync , sort 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 dois lançamentos dokuwiki para ver quais arquivos foram alterados e quais foram criados recentemente.
Buscamos os alcatrões com o 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 os arquivos recém-criados, como mostra a comparação do rsync e do diff aqui:
rsync -rcn --out-format="%n" old/ new/
produz a seguinte saída:
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
A execução do rsync apenas em uma direção perde os arquivos recém-criados e, ao contrário, os arquivos excluídos são comparados, compare a saída do diff:
diff -qr old/ new/
produz a seguinte saída:
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 o 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 a seguinte saída:
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 estes argumentos:
-r
"recursar 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 tempo e tamanho da modificação",
-n
para "executar uma avaliação sem alterações feitas" e
--out-format="%n"
para "gerar atualizações usando o FORMAT especificado", que é "% n" aqui apenas para o nome do arquivo
A saída (lista de arquivos) de rsync
ambas as direções é combinada e classificada usando sort
, e essa lista classificada é então condensada removendo todas as duplicatas comuniq