Remove linhas duplicadas de vários arquivos json enquanto preserva a estrutura do arquivo

0

Eu tenho uma pasta com milhares de arquivos json. O conteúdo de cada pasta é algo como isto:

file.1424-417982.json
file.1424-417995.json
file.1424-418013.json
file.1424-418015.json
(etc.)

Alguns dos arquivos contêm linhas duplicadas em outros arquivos da pasta. Por exemplo, a linha única

{"a":"fas8d\U0001f638f8gej3","b":527239835}

Pode ocorrer em

file.1424-417982.json
file.1424-418013.json

ou em alguns outros arquivos.

Eu gostaria de executar um script que passa por todos os arquivos, registra quais linhas são duplicadas em qualquer um dos arquivos e remove todas as ocorrências duplicadas dos arquivos (mantendo a primeira ocorrência).

Eu tentei

sort -u *.json > newfile

e criei um único arquivo enorme com as linhas exclusivas em todos os arquivos, mas isso não é útil para mim. Eu gostaria de preservar a estrutura de arquivos existente. Obrigado por qualquer dica!

    
por Zwentibold 23.11.2016 / 14:14

2 respostas

1

Supondo que seus nomes de arquivos não tenham espaços ou caracteres especiais, isso deve funcionar para você. Você pode ter que ajustar o primeiro comando para obter a ordem de classificação desejada para quais arquivos serão trabalhados primeiro.

#!/bin/bash
temp=$(mktemp)
for file_to_dedupe in $(echo *.json|sort)
do
   for file_to_strip in *.json
   do
      [ "$file_to_dedupe" == "$file_to_strip" ] && continue
      grep -w -Ff ${file_to_dedupe} -v ${file_to_strip} > ${temp}
      mv ${temp} ${file_to_strip}
   done
done

Explicação

  • temp=$(mktemp) cria um arquivo tmp com o qual trabalhar com
  • for file_to_dedupe in $(echo *.json|sort) inicia o loop para que os arquivos sejam duplicados.
  • for file_to_strip in *.json inicia o loop pelos arquivos para remover as duplicatas de.
  • [ "$file_to_dedupe" == "$file_to_strip" ] && continue pula nosso arquivo atual.
  • grep -w -Ff ${file_to_dedupe} -v ${file_to_strip} > ${temp} remove os dupes exatos usando cada linha como um padrão de file_to_dedupe
  • mv ${temp} ${file_to_strip} colocou o novo arquivo no lugar.
por 23.11.2016 / 15:05
0
perl -i.bak -ne 'print $_ unless $a{$_}++ '  *.json

e remova files.bak se funcionou.

    
por 17.01.2017 / 13:19