Como encontrar arquivos com o mesmo nome, mas diferentes contagens de linha em dois diretórios?

2

Eu tenho um diretório sub1 com os seguintes arquivos:

$ wc -l *

5 file1.csv
5 file3.csv
1 file4.csv

Em sub2 , tenho o seguinte:

$ wc -l *
5 file1.csv
5 file2.csv
1 file3.csv
5 file4.csv
1 file5.csv

No primeiro diretório, posso ter arquivos com linhas adicionadas, que então vão para o segundo diretório. Neste exemplo, posso precisar atualizar file3 em sub2 .

Como faço para obter uma lista dos arquivos com diferenças?

Eu fiz alguns testes com diff e grep , mas isso não funciona porque os diretórios têm arquivos diferentes (e, portanto, as linhas são diferentes):

~/dir1/$ wc -l >> wc.luis

~/dir1/$ wc -l * | awk '{ gsub(/\/home.*dir1\//,""); print $0 }' 
                 | diff --side-by-side wc.luis -
                 | grep \|

O ideal seria obter uma lista como esta:

5 file3.csv | 1 file3.csv
1 file4.csv | 5 file4.csv

Qualquer ajuda é apreciada!

Notas:

  • Não consigo verificar a data, porque todos os arquivos foram atualizados, com ou sem alterações.

  • Às vezes, os arquivos mais recentes faltam algumas linhas, motivo pelo qual não posso simplesmente pegar o maior.

por Luis 05.09.2016 / 18:27

1 resposta

1

Aqui está um "one-liner" de shell rápido e sujo com saída de exemplo:

$ join -j2 <(cd sub1; wc -l *) <(cd sub2; wc -l *) | awk '$2!=$3'
file3.csv 5 1
file4.csv 1 5
total 11 17

A linha total é um artefato da saída de wc . Pode ser removido com outro filtro:

$ join -j2 <(cd sub1; wc -l *) <(cd sub2; wc -l *) | awk '$2!=$3' | head -n-1
file3.csv 5 1
file4.csv 1 5

Explicação:

join unirá dois arquivos com base em uma coluna comum. Neste caso nós nos juntamos com base na segunda coluna ( -j2 ). Na saída de wc , a segunda coluna é o nome do arquivo. Isso só imprimirá arquivos comuns em ambos os diretórios.

As invocações de wc são feitas em substituições de processos com o diretório de trabalho alterado para sub1 ou sub2 para que os nomes dos arquivos sejam impressos sem o nome do diretório. Isso é para que join possa encontrar os arquivos comuns.

O comando awk compara o valor na segunda e terceira coluna e imprime apenas a linha se os valores forem diferentes. Isso filtrará os arquivos com a mesma contagem de linhas.

head -n-1 imprime todas as linhas, mas não a última linha. Isso filtrará a última linha total de wc .

    
por 05.09.2016 / 22:24