我有一个选项卡有限的数据读取
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最后一列是一个或多个由空格分隔的单词的组合。我希望在最后一栏中计算唯一值的数目,并将其替换为该组所特有的数字。我知道我可以用
awk -F '\t' '{print $NF}' infile | sort | uniq | wc -l但是我该怎么用数字来代替呢?例如,将所有的黑天鹅替换为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我还想生成给特定值的数字列表,如
Black Swan 1
Golden Duck 2
Brown Eagle 3
Sparrow 4发布于 2014-05-09 14:03:08
您可以使用关联数组来增加每个不同名称的计数器:
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它产生:
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发布于 2014-05-09 14:19:41
我开始写这个所以我要写完:
awk '
BEGIN {FS = OFS = "\t"}
{
last[$NF] = (last[$NF] ? last[$NF] : ++cnt)
$NF = last[$NF]
line[NR] = $0
}
END {
for (nr=1; nr<=NR; nr++)
print line[nr]
for (name in last)
print name, last[name]
}' file
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
Brown Eagle 3
Black Swan 1
Sparrow 4
Golden Duck 2更新:
下面是一个perl备选方案:
perl -F'\t' -lane '
$h{$F[-1]} = ++$c unless exists $h{$F[-1]};
$F[-1] = $h{$F[-1]};
print join "\t", @F }{ print "$_ $h{$_}" for keys %h
' file
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
Black Swan 1
Sparrow 4下面是基于mpapec's优秀评论的另一个更新:
perl -F'\t' -lane '
$F[-1] = $h{$F[-1]} ||= ++$c;
print join "\t", @F }{ print "$_ $h{$_}" for keys %h
' file 发布于 2014-05-09 14:03:34
您要做的是创建一组唯一的数据。set是包含所有唯一元素的字典或哈希表。在创建集合之后,可以搜索它并用适当的值替换字符串。
以下是帮助您解决问题的另一个设置链接:
http://world.std.com/~swmcd/steven/perl/pm/set.html
https://stackoverflow.com/questions/23566361
复制相似问题