在列中查找唯一值,并将唯一值替换为数字

dis*_*lus 3 unix perl awk replace

我有一个标签限制数据读取

1 0 0 1 1 Black Swan
0 0 1 0 0 Golden Duck
1 0 0 1 0 Brown Eagle
0 0 1 0 1 Golden Duck
1 0 0 1 0 Black Swan
1 0 1 0 0 Golden Duck
1 0 0 1 1 Sparrow
Run Code Online (Sandbox Code Playgroud)

最后一列是由空格分隔的一个或多个单词的组合.我想计算最后一列中唯一值的数量,并将其替换为该组唯一的数字.我知道我可以计算并列出使用的数字

awk -F '\t' '{print $NF}'  infile | sort | uniq | wc -l
Run Code Online (Sandbox Code Playgroud)

但是如何用数字替换?例如,将所有黑天鹅替换为1,将所有金鸭替换为2等.我希望结果如下:

1 0 0 1 1 1
0 0 1 0 0 2
1 0 0 1 0 3
0 0 1 0 1 2
1 0 0 1 0 1
1 0 1 0 0 2
1 0 0 1 1 4
Run Code Online (Sandbox Code Playgroud)

我还想生成给定特定值的数字列表

Black Swan 1
Golden Duck 2
Brown Eagle 3
Sparrow 4
Run Code Online (Sandbox Code Playgroud)

Bir*_*rei 5

您可以使用关联数组为每个不同的名称递增计数器:

awk '
    BEGIN { 
        FS = OFS = "\t" 
        i = 0
    }
    {
        if (! names[$NF]) {
            names[$NF] = ++i
        }
        $NF = names[$NF]
        print $0
    }
    END {
        for (name in names) {
            printf "%s %d\n", name, names[name]
        }
    }
' infile
Run Code Online (Sandbox Code Playgroud)

它产生:

1       0       0       1       1       1
0       0       1       0       0       2
1       0       0       1       0       3
0       0       1       0       1       2
1       0       0       1       0       1
1       0       1       0       0       2
1       0       0       1       1       4
Golden Duck 2
Brown Eagle 3
Sparrow 4
Black Swan 1
Run Code Online (Sandbox Code Playgroud)