我有 3 個帶有一些唯一 ID 的文字文件,我想在每個文字檔案中僅保留唯一 ID。假設有 3 個檔案(A、B 和 C)。如果A和B中都出現了ID“abc”,則需要將其從兩個檔案中刪除。
檔案已排序,大小小於 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