更改列中值的数量

更改列中值的数量

我有一个像这样的文件示例:

2931
7895
6688
7895
2931
2931
6688

我想生成一个包含此列和另一列的文件,如下所示:

2931 1
7895 2
6688 3
7895 2
2931 1
2931 1
6688 3

答案1

您需要为每种新类型的内容指定一个编号,然后在具有相同内容的每一行上显示该编号?

awk '
    { if ( !seen[$0]++ ) {
       ind++ ; n[$0]=ind
      }
    }

    { print $0, n[$0] }
'

做你需要的

使用埃德·莫顿的建议可以简化并使其更像“awk”,如下所示:

awk '
   ! ($0 in n) { n[$0]=++ind }
               { print $0, n[$0] }
'

答案2

假设您希望第二列成为第一列中每个数字的唯一数字(问题中不清楚):

$ awk '$2 = ( (k = key[$1]) ? k : key[$1] = ++n )' file
2931 1
7895 2
6688 3
7895 2
2931 1
2931 1
6688 3

这会跟踪 中最近分配的数字n,以及关联数组 中第一列和生成的数字(“键”)之间的关联key。该变量只是一个非常小的优化,以避免在第一列中存在数字的情况下k取消引用两次。key

逻辑:

$1如果对应的键$2不为零,则分配对应的键(零表示未初始化,并且$1以前从未见过)。如果为零,则将下一个可用数字分配给该键,然后分配给该键$2

我们不需要明确print任何内容,因为表达式的结果将不为零。由于表达式的结果非零,因此它会触发默认操作,即打印当前(修改后的)记录。

该命令的一个稍微更通用的变体将使用整行作为值,然后在末尾添加一个新列,无论输入数据中存在多少列:

awk '$(NF+1) = ( (k = key[$0]) ? k : key[$0] = ++n )' file

用等效的“长手”语法拼写出代码:

awk '
{
    k = key[$0]

    if (k != 0)
        newval = k
    else
        newval = key[$0] = ++n

    print $0, newval
}' file

相关内容