Respostas:
Na página do manual diff:
-q
Relate apenas se os arquivos diferem, não os detalhes das diferenças.
-r
Ao comparar diretórios, compare recursivamente todos os subdiretórios encontrados.
Comando de exemplo:
diff -qr dir1 dir2
Exemplo de saída (depende da localidade):
$ ls dir1 dir2
dir1:
same-file different only-1
dir2:
same-file different only-2
$ diff -qr dir1 dir2
Files dir1/different and dir2/different differ
Only in dir1: only-1
Only in dir2: only-2
-x PATTERN
no comando para excluir determinados subdiretórios. Por exemplo, diff -qr repo1 repo2 -x ".git"
comparará dois diretórios, mas excluirá os caminhos de arquivo com ".git" neles.
Você também pode usar o rsync
rsync -rv --size-only --dry-run /my/source/ /my/dest/ > diff.out
--size-only
perderá arquivos de tamanho idêntico, mas com conteúdo diferente, por exemplo, old / version.txt "29a" new / version.txt "29b" . Use em vez disso: rsync -ric --dry-run old/ new/
onde o argumento "-i" permite obter a lista de arquivos diretamente viarsync -ric --dry-run old/ new/ | cut -d" " -f 2
Se você deseja obter uma lista de arquivos que estão apenas em um diretório e não seus subdiretórios e apenas seus nomes de arquivo:
diff -q /dir1 /dir2 | grep /dir1 | grep -E "^Only in*" | sed -n 's/[^:]*: //p'
Se você deseja listar recursivamente todos os arquivos e diretórios diferentes com seus caminhos completos:
diff -rq /dir1 /dir2 | grep -E "^Only in /dir1*" | sed -n 's/://p' | awk '{print $3"/"$4}'
Dessa forma, você pode aplicar comandos diferentes a todos os arquivos.
Por exemplo, eu poderia remover todos os arquivos e diretórios que estão no dir1, mas não no dir2:
diff -rq /dir1 /dir2 | grep -E "^Only in /dir1*" | sed -n 's/://p' | awk '{print $3"/"$4}' xargs -I {} rm -r {}
No meu sistema linux para obter apenas os nomes de arquivos
diff -q /dir1 /dir2|cut -f2 -d' '
audit-0.0.234/audit-data-warehouse-0.0.234/ audit-0.0.235/audit-data-warehouse-0.0.235/
diff -qrN /dir1 /dir2 | cut -f2 -d' '
funciona bem para mim!
A abordagem da execução diff -qr old/ new/
tem uma grande desvantagem: ela pode perder arquivos nos diretórios criados recentemente. Por exemplo, no exemplo abaixo, o arquivo data/pages/playground/playground.txt
não está na saída de diff -qr old/ new/
enquanto o diretório data/pages/playground/
está (procure playground.txt no seu navegador para comparar rapidamente). Também publiquei a seguinte solução no Unix e Linux Stack Exchange , mas vou copiá-la aqui também:
Para criar uma lista de arquivos novos ou modificados programaticamente, 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 somente 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 arquivoA 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
diff new/ old/
) para ver quais diretórios foram excluídos?
diff -qr new/ old/
no exemplo acima com os dokuwiki tars produz a mesma saída que diff -qr old/ new/
- ou seja, você vê que o diretório é novo / ausente, mas não os arquivos nele
diff
página de manual no CentOS 7 descreve-q
como "reportar apenas quando os arquivos diferem", o que é menos claro do que o que você escreveu.