如何用"替换重复的行。"在awk?

时间:2016-08-09 14:33:19

标签: bash awk duplicates

我需要用#34;替换第一列中的重复。"

例如:

name1
name1
name1
name2
name2
name3
name3

我需要输出:

name1
.
.
name2
.
name3
.

我有这样的解决方案:

awk '{c=$1} c==p{gsub(/./,".",$1)} {p=c} 1' in.file

但输出是:

name1
.....
.....
name2
.....
name3
.....

有没有任何其他管道的解决方案?

3 个答案:

答案 0 :(得分:6)

使用数组检查是否已经看到一行!

$ awk 'seen[$0]++ {$0="."}1' file
name1
.
.
name2
.
name3
.

跳过重复行的典型方法是说awk '!seen[$0]++' file。这里我们使用相同的逻辑但稍微扭曲它:我们使用数组seen[]来检查到目前为止是否出现了一条线。如果有,seen[$0]++将大于0,那么{$0="."}将会出现。然后,1打印此行或行。

如果您碰巧需要检查整行而不是已定义的列,请将$0(完整记录)替换为$n,其中n是n 字段。

答案 1 :(得分:3)

此函数调用:

gsub(/./,".",$1)

将模式/./每个匹配替换为字符串"."。给出的正则表达式匹配任何单个字符,因此您要求完全遵循您观察到的行为:重复名称中的每个字符都替换为"。"。

有很多方法可以修复它;其中包括执行你真正意义上的替换:

sub(/.*/, ".", $1)

这不是最佳实施,但它在原始代码中展示了这个问题。

答案 2 :(得分:1)

您可以在*内的模板中添加gsub,以匹配整行:

awk '{c=$1} c==p{gsub(/.*/,".",$1)} {p=c} 1'