Как найти уникальные строки из каждого файла, учитывая 3 текстовых файла

Как найти уникальные строки из каждого файла, учитывая 3 текстовых файла

У меня есть 3 текстовых файла с уникальными идентификаторами, и я хочу сохранить только уникальные идентификаторы в каждом текстовом файле. Допустим, есть 3 файла (A, B и C). Если идентификатор "abc" появляется в A и B, его нужно удалить из обоих файлов.

Файлы отсортированы и имеют размер менее 1 МБ, а идентификаторы — это алфавитно-цифровые символы. Также внутри каждого файла нет дубликатов.

Есть ли способ сделать это просто с помощью инструментов командной строки в Linux или Mac? Я думал написать код изначально, но хотел сначала спросить. Спасибо!

решение1

Предположения:

  • текстовые файлы имеют один идентификатор на строку
  • каждая строка содержит только идентификатор и никакого другого текста
  • идентификаторы не повторяются в файле
  • можно изменить порядок выходного файла (отсортировать его)
  • эффективность исполнения не важна
  • Идентификаторы являются буквенно-цифровыми.
$ cat A B B C C | sort | uniq -u >A.uniq
$ cat B A A C C | sort | uniq -u >B.uniq
$ cat C A A B B | sort | uniq -u >C.uniq
$ mv A.uniq A
$ mv B.uniq B
$ mv C.uniq C

Команда 'cat' объединяет перечисленные файлы вместе. Первый файл — это тот, который я хочу удалить из дубликатов. Следующие файлы — потенциальные дубликаты, которые я хочу удалить. Я добавляю две копии каждого из этих файлов, чтобы гарантировать, что они дублируются и будут удалены.

Затем я «сортирую» эти файлы вместе в алфавитном порядке. Это приводит к тому, что любые дублирующиеся идентификаторы оказываются на соседних строках в отсортированном выводе.

Команда 'uniq' с опцией '-u' выводит только строки, которые являются uniq. Если два или более одинаковых идентификатора появляются в соседних строках во входных данных, ничего не выводится.

Символ «>» записывает вывод в новый файл с именем «A.uniq».

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

$ cat A B C | sort | uniq -d >duplicates

Команда «uniq» с флагом «-d» выводит строку только в том случае, если она повторяется во входных данных два или более раз.

решение2

Спасибо за отвлечение - я придумал следующий сценарий (задокументированный) -

#! /bin/bash

SOURCEFILES="./existing/list1.txt  ./existing/list2.txt  ./existing/list3.txt"

# First find a list of duplicate files.  We do this by catting all files and finding where there are lines that are not unique

# $DUPLICATES will be a space seperated list of duplicate IDs

DUPLICATES=$( cat $SOURCEFILES | sort | uniq -d )
echo "Duplicates Found for removal: " $DUPLICATES

# Convert list of duplicates into a pipe seperated list
# Commented out version assumes all ID's are all the same length, so it would break if one is ABC and another is ABCD 
#DUPLICATES=$( echo $DUPLICATES | tr ' ' '|' )

# This version translates the duplicate REGEX to say that each line is complete 
# ^ means start of line and $ means end of line.

for each in $DUPLICATES
do
    DUPLIST="$DUPLIST^$each$|"
done

# Remove trailing "|" from DUPLIST
DUPLICATES=$( echo ${DUPLIST::-1} )


# Go through each file, removing duplicates 
for each in $SOURCEFILES
do
    mv $each $each.old
    egrep -v "$DUPLICATES" < $each.old > $each
done

Связанный контент