Удаление дублирующихся строк из нескольких json файлов с сохранением структуры файла

У меня есть папка с тысячами json-файлов. Содержимое каждой папки выглядит примерно так:

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

Некоторые из файлов содержат строки, которые дублируются в других файлах в папке. Например, одна строка

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

может встречаться в

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

или в некоторых других файлах.

Я хотел бы запустить сценарий, который просматривает все файлы, записывает, какие строки дублируются в любом из файлов, затем удаляет все дубликаты из файлов (сохраняя первое вхождение).

Я пробовал

sort -u *.json > newfile

и создал огромный единый файл с уникальными строками во всех файлах, но это мне не подходит. Я хотел бы сохранить существующую структуру файлов. Спасибо за любые советы!

0
23.11.2016, 16:06
2 ответа

Если в именах файлов нет пробелов или специальных символов, это должно сработать для вас. Возможно, вам придется настроить первую команду, чтобы получить желаемый порядок сортировки, для которого файлы обрабатываются в первую очередь.

#!/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

Объяснение

  • temp = $ (mktemp) создать tmp-файл, который будет работать с
  • для file_to_dedupe в $ (echo * .json | sort) начать цикл для файлов для дедупликации .
  • для file_to_strip в * .json начать цикл по файлам, чтобы удалить дубликаты.
  • ["$ file_to_dedupe" == "$ file_to_strip"] && continue пропустить текущий файл.
  • grep -w -Ff $ {file_to_dedupe} -v $ {file_to_strip}> $ {temp} удалить точные дубли, используя каждую строку в качестве шаблона из file_to_dedupe
  • mv $ {temp} $ {file_to_strip} поместил новый файл на место.
1
28.01.2020, 02:47
perl -i.bak -ne 'print $_ unless $a{$_}++ '  *.json

и удалить files.bak , если это сработало.

0
28.01.2020, 02:47

Теги

Похожие вопросы