Exclui arquivos idênticos salvos como saída em um log

2

Eu tenho três arquivos em duas pastas. Os arquivos são nomeados, a.txt , b.txt e c.txt estavam localizados nas pastas A e B . Eu usei um aplicativo Full File Mini Comparer que compara a pasta e salva para logar na pasta A .

O log tem um texto como segue:

Different: A=/sdcard/A/a.txt B=/sdcard/B/a.txt
Same: A=/sdcard/A/b.txt B=/sdcard/B/b.txt
Different: A=/sdcard/A/c.txt B=/sdcard/B/c.txt

Como posso usar sed e rm ou talvez algum outro comando para remover / excluir os arquivos "Same" permanentemente.

    
por PJ547 12.10.2018 / 16:00

3 respostas

9

Você tem

$ tree
.
|-- A
|   |-- a.txt
|   |-- b.txt
|   '-- c.txt
'-- B
    |-- a.txt
    |-- b.txt
    '-- c.txt

2 directories, 6 files

Usando fdupes :

$ fdupes -1 A B
A/b.txt B/b.txt

fdupes detecta duplicatas com base no conteúdo do arquivo. O sinalizador -1 faz com que ele exiba os nomes de arquivos de cada conjunto de duplicatas em uma única linha. Aqui, ele detecta que os arquivos b.txt são idênticos.

Você pode usar fdupes para excluir duplicatas:

$ fdupes --delete A B
[1] A/b.txt
[2] B/b.txt

Set 1 of 1, preserve files [1 - 2, all]: 1

   [+] A/b.txt
   [-] B/b.txt

Ele interativamente pergunta qual arquivo manter (ou manter ambos). Eu escrevi 1 , então o arquivo A/b.txt foi mantido enquanto B/b.txt foi deletado.

Consulte o manual para fdupes ( man fdupes ). Se não estiver instalado em seu sistema, use um gerenciador de pacotes para instalá-lo. Ele também pode ser feito para excluir automaticamente os arquivos sem a solicitação interativa, mas é preciso ter cuidado ao executá-lo dessa maneira. Sempre faça um backup dos seus dados antes de executar um comando que possa excluir arquivos.

Observe que fdupes sempre manterá pelo menos um dos duplicados. Se você deseja excluir todas as duplicatas, talvez esteja interessado nesta versão corrigida de fdupes mencionada em uma resposta a uma pergunta semelhante feita em SuperUser: link (eu não testei isso).

O motivo pelo qual sugiro usar fdupes em vez de analisar o arquivo de log que você tem é que os nomes de arquivo incorporados em um documento de texto são difíceis de analisar corretamente. Pode não ser sempre difícil (e neste exemplo em particular, seria fácil), mas note que o Unix permite tanto espaços quanto novas linhas nos nomes de arquivos e diretórios. É tecnicamente possível ter um diretório chamado

a.txt
Same: A=

com uma nova linha incorporada no nome.

    
por 12.10.2018 / 16:54
2

com awk :

awk -F'[:]' '/Same:/{print $0}' logfile | xargs -n1 | awk -F'=' '{print $2}' | xargs rm -rf

awk procura a linha no arquivo de log que contém a palavra-chave "Mesmo:" e, em seguida, xargs organiza as variáveis e os caminhos (isto é, A = ***) um por linha, depois awk captura o caminho absoluto. Na etapa final, xargs chama rm para excluir os caminhos.

Você deve estar ciente de que quando xargs solicitar rm para excluir os caminhos, isso excluirá os arquivos definitivamente. O sinalizador -I pode ser adicionado a rm para lembrar o usuário de confirmar a exclusão.

rm man

-I solicitar uma vez antes de remover mais de três arquivos ou                           ao remover recursivamente; menos intrusivo que -i,                           enquanto ainda dá proteção contra a maioria dos erros

ou com grep

grep "Same:" logfile | grep -oP '/[^ ]*' | xargs rm -rf

O primeiro grep encontra a linha que contém a palavra-chave Same .

O segundo grep preenche o arquivo de log para se livrar de tudo, exceto dos caminhos relevantes para a palavra-chave. Por fim, xargs chama rm para excluir os caminhos.

    
por 12.10.2018 / 17:46
2

Você REALMENTE deseja excluir todos os arquivos idênticos ou apenas n-1 e manter uma cópia? Então, por que não

awk  '/Same:/ {for (i=2; i<=NF; i++) {split ($i, T, "="); print "rm", T[2]}}' log 
rm /sdcard/A/b.txt
rm /sdcard/B/b.txt

e canalize para sh quando estiver satisfeito com o resultado. Se você quiser também manter uma cópia, inicie o loop a partir de i=3 .

Ou, uma abordagem diferente sem awk :

echo rm $(md5sum path/to/files* | sort | uniq -Dw33 | cut -d" " -f3-)
rm file2 file4

Remova o echo se estiver satisfeito com o resultado. Se os arquivos tiverem espaços em seus nomes, etapas adicionais precisam ser tomadas.

    
por 12.10.2018 / 18:08

Tags