假设我有两行(在 txt 文件中)
Monday, Tuesday, Week
Tuesday, Monday, Week
它们包含相同的信息,但信息(第一列和第二列)在每行中的顺序不同,因此我不能简单地使用sort
, 或uniq
来摆脱它们。
如何删除包含相同信息的所有重复行?
答案1
和perl
:
perl -lne 'print unless $seen{join ",", sort split /,\h*/}++'
答案2
如果您不关心是否保留文件中看到的行中的顺序,则可以将每一行采用标准(或规范)格式,然后使用 sort/uniq 或类似的。
由于您已经补充说您确实关心保留文件中表示的顺序之一,因此我采取的方法是将每一行排序为规范顺序,并将其与原始行一起输出,然后对第一个规范化的行进行排序表示为关键点,并删除具有重复关键点的行,然后修剪掉该关键点。
这是第一部分。它在每个原始行前面加上行内容的规范化表示:
( while read f; do echo $f | tr -d "," | tr " " "\n" | sort | tr "\n" " " ; echo ':' $f ; done < data ) | awk -F":" '!_[$1]++' | cut -f2 -d: |cut -c2-
您可以运行其中的一部分来查看它的作用。第一部分发出带有规范化表示(按词法排序)的原始记录,并带有 : 分隔符:
$ cat data
Monday, Tuesday, Week
Tuesday, Monday, Week
Tuesday, Thursday, Week
Week, Thursday, Tuesday
$ ( while read f; do echo $f | tr -d "," | tr " " "\n" | sort | tr "\n" " " ; echo ':' $f ; done < data )
Monday Tuesday Week : Monday, Tuesday, Week
Monday Tuesday Week : Tuesday, Monday, Week
Thursday Tuesday Week : Tuesday, Thursday, Week
Thursday Tuesday Week : Week, Thursday, Tuesday
然后,我使用 awk 构建一个哈希,其中包含每次看到某个键的计数,并且由于不包含“!”,因此每个键的第一个实例都有隐式打印。
$ ( while read f; do echo $f | tr -d "," | tr " " "\n" | sort | tr "\n" " " ; echo ':' $f ; done < data ) | awk -F":" '!_[$1]++' | cut -f2 -d: |cut -c2-
Monday, Tuesday, Week
Tuesday, Thursday, Week
答案3
棘手的解决方案(这只是一个示例)- 在我的 bash 中工作正常。所有行/单词都可以按字符拆分,然后可以对这些字符进行排序。如果排序后的行 1 = 排序后的行 2,则您有重复项。
word1+=( $(echo "this is my life" |fold -w1) )
sortedword1=($(echo ${word1[@]} | tr " " "\n" | sort))
word2+=( $(echo "is this my life" |fold -w1) )
sortedword2=($(echo ${word1[@]} | tr " " "\n" | sort))
echo "${sortedword1[@]}"
echo "${sortedword2[@]}"
if [[ $sortedword1 == $sortedword2 ]]; then
echo "Word 1 and Word 2 are the same, delete one of them"
fi
输出:
e f h i i i l m s s t y
e f h i i i l m s s t y
Word 1 and Word 2 are the same, delete one of them