以下问题对我来说很奇怪。
考虑以下日志文件:
--------------------------------------------------
----- 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是更受欢迎的)
答案 0 :(得分:1)
您可以做的一件事是在shell脚本中使用awk
来跟踪原始名称和新生成的名称之间的映射。这个特殊的awk脚本通过比较NR
和FNR
内置变量来分别处理第一个文件,这些变量分别计算处理的记录总数和当前文件中处理的记录数。有关此技巧的更多信息,请访问: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), dict, global, if, namespace, proc, return, set, variable