当我注意到它没有按预期工作时,我试图应用此处提出的方法{Removing duplicates on a variable without sorting}来删除字符串中的重复项。
例如,假设我们有:
s="apple apple tree appleapple tree"
删除重复项我们希望得到以下输出:
apple tree appleaplle
应该通过将以下命令应用于字符串(链接中的完整说明)来获得:
awk 'BEGIN{RS=" "; ORS=" "}{ if(a[$0] == 0){a[$0]+=1; print $0}}' <<< $s
它使用关联数组,因此我们不希望打印两次相同的记录。但是,按照这种方法,我得到了这个
apple tree appleapple tree
根据需要删除了第一个apple
副本,但不是最后一个。
事实上,如果我们打印每条记录的长度,我们会看到最后一条记录不是tree
而是tree
+返回字符(我想是这样)。
$ awk 'BEGIN{RS=" "; ORS=" "}{ print length($0); print $0}' <<< $s
$ 5 apple 5 apple 4 tree 10 appleapple 5 tree
请注意,最后一棵树确实是5个字符而不是4个字符,导致破坏关联数组方法。
我不明白为什么会有这个角色,它来自哪里? 以及如何解决此问题以使用此方法删除重复项?
非常感谢您的任何建议
答案 0 :(得分:3)
如上所述,通过将RS设置为" "
,这意味着\n
不再是记录之间的字符,因此它将成为输入行"tree\n"
上最后一个字段的一部分。
FWIW如果您有多字符RS的GNU awk,您可以这样做:
awk -v RS='\\s+' '!seen[$0]++{printf "%s%s", (NR>1?OFS:""), $0} END{print ""}'
答案 1 :(得分:2)
此示例显示您怀疑是正确的:
$ echo "apple apple tree appleapple tree" | awk 'BEGIN{RS=" "; ORS=" "}
{ printf("%s |%s| ", length($0), $0)}'
5 |apple| 5 |apple| 4 |tree| 10 |appleapple| 5 |tree
|
我会使用FS来获取所有不同的值,如下所示:
$ echo "apple apple tree appleapple tree" | awk '{for (i=1; i<=NF; i++)
printf "%s %s\n", length($i), $i}'
5 apple
5 apple
4 tree
10 appleapple
4 tree
摆脱双打:
echo "apple apple tree appleapple tree" | awk 'BEGIN{ORS=" "}{for (i=1;
i<=NF; i++)a[$i]++} END {for (i in a) print i }'
答案 2 :(得分:2)
如果您不需要维护单词顺序:
$ ( set -f; printf "%s\n" $s | sort -u | paste -sd" " )
apple appleapple tree
如果您确实想要保留订单:
$ awk '
{
delete seen
sep=""
for (i=1; i<=NF; i++) {
if (!seen[$i]++) {
printf "%s%s", sep, $i
}
sep=OFS
}
print ""
}
' <<<"$s"
apple tree appleapple
答案 3 :(得分:0)
这是我对重复记录所做的:
awk '{if(arr[$1]!="true") print $1; arr[$1]="true"}' file.txt