Bash / Tcl:如何重命名位于文本文件中同一列的随机生成的名称?

时间:2017-03-19 19:34:36

标签: bash tcl

以下问题对我来说很奇怪。

考虑以下日志文​​件:

--------------------------------------------------
-----                INPUT DATA              -----
--------------------------------------------------
           NAME                    Atribute1   Atribute2
--------------------------------------------------
name                               0           0
name1                              8           7 
name5                              3           3   
name3                              4           2
name22                             5           8

...
//Skipped ....                            ...     

---------------------------------------------------
-----                INPUT DATA               -----
---------------------------------------------------
           NAME                    Attribute1   Attribute2 
---------------------------------------------------
name10                             0            0
name1                              8            7
name3                              0            0
name22                             0            0
name33                             9            0
name45                             0            0
...                                                  ...
//Skipped ....

生成第一列的名称,实际上我对它们一无所知

问题: 如何重命名第一列中的所有名称以获得如下内容:

--------------------------------------------------
-----                INPUT DATA              -----
--------------------------------------------------
           NAME                    Atribute1   Atribute2
--------------------------------------------------
x                                      0        0
x1                                     8        7 
x2                                     3        3   
x3                                     4        2
x4                                     5        8

---------------------------------------------------
-----                INPUT DATA                       -----
---------------------------------------------------
           NAME                    Attribute1   Attribute2 
---------------------------------------------------
x5                                  0           0
x1                                  8           7
x3                                  0           0
x6                                  0           0
x7                                  9           0
x8                                  0           0
x9                                  0           0
x10                                 0           0

即用x-es重命名初始名称:" x1,x2 ...."

限制:应将同一x(i)分配给重复的名称。 如示例所示:name1和name3也存在于第二个表中,因此它们的新名称在两个表(x1,x3)中都是相同的。

我正在寻找bash或tcl的解决方案(bash是更受欢迎的)

2 个答案:

答案 0 :(得分:1)

您可以做的一件事是在shell脚本中使用awk来跟踪原始名称和新生成的名称之间的映射。这个特殊的awk脚本通过比较NRFNR内置变量来分别处理第一个文件,这些变量分别计算处理的记录总数和当前文件中处理的记录数。有关此技巧的更多信息,请访问:https://unix.stackexchange.com/questions/106645/processing-two-files-using-awk

基本上,此程序会跟踪计数器c和字典name,它将原始名称映射到新名称(只有c,前缀为{{1} }})。

还有两种线。标题行以"x""-"开头,将被忽略并按原样打印。

您可能需要做的一件事是之后拆分文件,除非文件应该连接在一起。

" "

请注意,此程序不进行格式化,#!/bin/sh awk ' BEGIN { c = 0; } /^[- ]/ { print; } /^[^- ]/ && NR == FNR { new_name = "x" c; name[$1] = new_name; c += 1; $1 = new_name; print; } /^[^- ]/ && NR != FNR { if ($1 in name) { $1 = name[$1]; } else { new_name = "x" c; c += 1; $1 = new_name; } print; } ' input.txt input2.txt 具有awk函数,可用于格式化具有固定列数的数据。

答案 1 :(得分:1)

Tcl:使用字典。如果名称已存在。如果没有,请将其添加到字典中。无论哪种方式,都要给出替换名称。

set names {}
proc lookup name {
    global names
    if {![dict exists $names $name]} {
        dict set names $name [dict size $names]
    }
    return x[dict get $names $name]
}

如果全局打扰你,你可以将它们隐藏在命名空间中:

namespace eval names {
namespace export lookup
    variable names
    set names {}
    proc lookup name {
        variable names
        if {![dict exists $names $name]} {
            dict set names $name [dict size $names]
        }
        return x[dict get $names $name]
    }
}

文档: ! (operator)dictglobalifnamespaceprocreturnsetvariable