3개의 텍스트 파일이 있는 경우 각 파일에서 고유한 줄을 찾는 방법

3개의 텍스트 파일이 있는 경우 각 파일에서 고유한 줄을 찾는 방법

고유한 ID를 가진 3개의 텍스트 파일이 있고 각 텍스트 파일에 고유한 ID만 유지하고 싶습니다. 3개의 파일(A, B, C)이 있다고 가정해 보겠습니다. A와 B에 "abc"라는 ID가 나타나면 두 파일 모두에서 이를 제거해야 합니다.

파일은 정렬되어 있으며 크기는 1MB 미만이고 ID는 영숫자입니다. 또한 각 파일 내에는 중복된 내용이 없습니다.

Linux나 Mac에서 명령줄 도구를 사용하여 이 작업을 수행할 수 있는 방법이 있습니까? 처음에 코드를 작성하려고 생각하고 있었는데 먼저 물어보고 싶었습니다. 감사해요!

답변1

가정:

  • 텍스트 파일은 한 줄에 단일 ID를 갖습니다.
  • 각 줄에는 ID만 포함되고 다른 텍스트는 포함되지 않습니다.
  • ID는 파일 내에서 반복되지 않습니다.
  • 출력 파일을 다시 정렬해도 괜찮습니다(정렬).
  • 실행 효율성은 중요하지 않습니다
  • ID는 영숫자입니다.
$ 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' 명령은 나열된 파일을 함께 연결합니다. 첫 번째 파일은 중복된 파일을 제거하려는 파일입니다. 다음 파일은 제거하고 싶은 잠재적인 중복 파일입니다. 나는 이 파일들이 중복되어 제거될 것임을 보장하기 위해 각 파일의 사본 두 개를 추가합니다.

다음으로, 이 파일들을 알파벳순으로 '정렬'합니다. 이로 인해 정렬된 출력에서 ​​인접한 줄에 중복된 ID가 표시됩니다.

'-u' 옵션이 포함된 'uniq' 명령은 uniq인 라인만 출력합니다. 입력에서 인접한 라인에 동일한 ID가 두 개 이상 나타나면 아무것도 출력되지 않습니다.

'>'는 'A.uniq'라는 새 파일에 출력을 씁니다.

반대 작업을 수행하여 3개 파일에 중복된 모든 ID 목록을 생성하려면 다음과 같이 할 수 있습니다.

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

'-d' 플래그가 포함된 'uniq' 명령은 입력에서 두 번 이상 반복되는 경우에만 한 줄을 출력합니다.

답변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

관련 정보