我有一个这样的文本文件:
id ; lorem ipsum fgdg df gdg
id ; lorem ipsum fgdg df gdg
id ; lorem ipsum fgdg df gdg
id ; lorem ipsum fgdg df gdg
id ; lorem ipsum fgdg df gdg
如果 2 id 相似,我想分开到 2 id 相似的行和唯一的行。
uniquefile
包含具有唯一 ID 的行。 notuniquefile
包含没有行的行。
我已经找到了一种方法来几乎做到这一点,但只能用第一个词。基本上,它只是隔离id并删除行的其余部分。
命令 1:隔离唯一 id(但缺少该行(:
awk -F ";" '{!seen[$1]++};END{for(i in seen) if(seen[i]==1)print i }' originfile >> uniquefile
命令 2:隔离不唯一的 id(但缺少该行并丢失可能因行而异的"lorem ipsum"内容(:
awk -F ":" '{!seen[$1]++;!ligne$0};END{for(i in seen) if(seen[i]>1)print i }' originfile >> notuniquefile
所以在一个完美的世界里,我希望你帮助我获得这种类型的结果:
originfile
:
1 ; toto
2 ; toto
3 ; toto
3 ; titi
4 ; titi
uniquefile
:
1 ; toto
2 ; toto
4 ; titi
notuniquefile
:
3 ; toto
3 ; titi
祝你今天开心。
另一种只有两个 unix 命令的方法,如果您的 id 字段始终具有相同的长度,则可以使用(假设它们的长度为一个字符,就像在我的测试数据中一样,但它当然也适用于更长的字段(:
# feed the testfile.txt sorted to uniq
# -w means: only compare the first 1 character of each line
# -D means: output only duplicate lines (fully not just one per group)
sort testfile.txt | uniq -w 1 -D > duplicates.txt
# then filter out all duplicate lines from the text file
# to just let the unique files slip through
# -v means: negate the pattern
# -F means: use fixed strings instead of regex
# -f means: load the patterns from a file
grep -v -F -f duplicates.txt testfile.txt > unique.txt
输出是(与我的另一篇文章中使用的输入行相同(:
$uniq -w 2 -D testfile.txt
2;line B
2;line C
3;line D
3;line E
3;line F
和:
$ grep -v -F -f duplicates.txt testfile.txt
1;line A
4;line G
顺便说一句,如果你想避免grep
,你也可以存储排序的输出(比如说在sorted_file.txt中(并将第二行替换为
uniq -w 1 -u sorted_file.txt > unique.txt
其中,-w
后面的数字是 id 字段的长度(以字符为单位(。
未经测试:处理文件两次:第一次计算 ID,第二次决定在何处打印记录:
awk -F';' '
NR == FNR {count[$1]++; next}
count[$1] == 1 {print > "uniquefile"}
count[$1] > 1 {print > "nonuniquefile"}
' file file
下面是一个执行此操作的小 Python 脚本:
#!/usr/bin/env python3
import sys
unique_markers = []
unique_lines = []
nonunique_markers = set()
for line in sys.stdin:
marker = line.split(' ')[0]
if marker in nonunique_markers:
# found a line which is not unique
print(line, end='', file=sys.stderr)
elif marker in unique_markers:
# found a double
index = unique_markers.index(marker)
print(unique_lines[index], end='', file=sys.stderr)
print(line, end='', file=sys.stderr)
del unique_markers[index]
del unique_lines[index]
nonunique_markers.add(marker)
else:
# marker not known yet
unique_markers.append(marker)
unique_lines.append(line)
for line in unique_lines:
print(line, end='', file=sys.stdout)
它不是一个纯粹的外壳解决方案(恕我直言,这将很麻烦且难以维护(,但也许它可以帮助您。
这样称呼它:
separate_uniq.py < original.txt > uniq.txt 2> nonuniq.txt
使用纯 bash 脚本,您可以像这样操作:
duplicate_file="duplicates.txt"
unique_file="unique.txt"
file="${unique_file}"
rm $duplicate_file $unique_file
last_id=""
cat testfile.txt | sort | (
while IFS=";" read id line ; do
echo $id
if [[ "${last_id}" != "" ]] ; then
if [[ "${last_id}" != "${id}" ]] ; then
echo "${last_id};${last_line}" >> "${file}"
file="${unique_file}"
else
file="${duplicate_file}"
echo "${last_id};${last_line}" >> "${file}"
fi
fi
last_line="${line}"
last_id="${id}"
done
echo "${last_id};${last_line}" >> "${file}"
)
输入文件为:
1;line A
2;line B
2;line C
3;line D
3;line E
3;line F
4;line G
它输出:
$ cat duplicates.txt
2;line B
2;line C
3;line D
3;line E
3;line F
work$ cat unique.txt
1;line A
4;line G