删除包含相同信息但顺序不同的行

删除包含相同信息但顺序不同的行

假设我有两行(在 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

相关内容