我有 3 个文本文件,每个文件都有一些唯一的 ID,我想在每个文本文件中只保留唯一的 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”命令仅输出唯一的行。如果输入中的相邻行中出现两个或多个相同 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