这个问题似乎与我的一个问题几乎相同,我在您的示例中使用了一列来解决我的问题:) 所以......
[[bash_prompt$]]$ cat log ; echo "########"; \
> cat test.sh ;echo "########"; awk -f test.sh log
heading1 heading2 numberlist group
name1 text 1,2,3
name2 text 2
name3 text 9
name4 text 1,4
name5 text 5,7
name6 text 7
name7 text 8
name8 text 6,2
########
/^name/{
i=0; j=0;
split($3,a,",");
for(var in a) {
for(var1 in q) {
split(q[var1],r,",");
for(var2 in r) {
if(r[var2] == a[var]) {
i=1;
j=((var1+1));
}
}
}
}
if(i == 0) {
q[length(q)] = $3;
j=length(q);
}
print $1 "\t\t" $2 " \t\t" $3 "\t\t" j;
}
########
name1 text 1,2,3 1
name2 text 2 1
name3 text 9 2
name4 text 1,4 1
name5 text 5,7 3
name6 text 7 3
name7 text 8 4
name8 text 6,2 1
[[bash_prompt$]]$
更新:
split
通过传入第三个参数的分隔符拆分第一个参数,并将其放入第二个参数指向的数组中。这里的主数组是 q,它保存了一个组的组成员,它基本上是一个数组数组,其中元素的索引是组 id,元素是组的所有成员的集合。soq[0]="1,2,3"
表示第 0 个组包含成员1
,2
和3
. name
现在在 awk 中,读取以( )开头的第一行/^name/
。然后将第三个字段 ( 1,2,3
) 分解为数组 a。现在对于数组 a 中的每个元素,我们将每个组存储到 q ( for(var1 in q)
) 中,然后在每个组内,我们将它们拆分为另一个临时数组 r (split(q[var1],r,",")
),即“1,2,3”被分割成一个数组r。现在将 r 中的每个元素与 a 中的元素进行比较。如果找到匹配项,则组的索引是该行的索引(数组索引从 0 开始,组从 1 开始,因此使用 ((var1+1))。现在如果没有找到,只需将其作为新组添加到 q 和最后一个索引 + 1,即数组的长度是该行的索引
更新:
/^name/{
j=0;
split($3,a,",");
for(var in a) {
if(q[a[var]] != 0) {
j=q[a[var]]; i=1;
break;
}
}
j = (j == 0) ? ++k : j;
for(var1 in a) {
if(q[a[var1]] == 0) {
q[a[var1]] = j;
}
}
print $1 "\t\t" $2 " \t\t" $3 "\t\t" j;
}
更新:
base 是 awk 具有关联数组,每个元素都由字符串键访问。早期的方法是将每个组存储在一个数组中,其中键是组的索引。因此,当我们读取列时,我们将读取每个组,将组拆分为单个元素,将每个元素与列中的每个元素进行比较。但是,如果我们将元素存储在一个数组中,而不是存储一个组,其中键是元素本身,键的值是元素所属组的索引。因此,当我们读取一列时,我们将列拆分为单个元素(split($3,a,",");
)然后检查数组中的元素是否存在以该元素为键的组索引if(q[a[var]] != 0)
(在 awk 中,如果该元素不存在,则默认为具有值的元素0 在那里初始化,所以检查q[a[var]] != 0
)。如果找到任何元素,我们将元素的组索引作为列的索引并中断。否则j
将保持 0。如果j
保持 0,++k
则给出最新的组索引。现在我们找到了列元素的组索引。需要为那些不属于任何其他组的元素携带该索引(会有同一列中的多个元素属于不同组的情况,这里我们采用先到先得的方法,但不要过度写入已经属于另一个组的其他人的组索引)。所以对于列 ( for(var1 in a)
) 中的每个元素,如果它不属于一个组 ( if(q[a[var1]] == 0)
) ,就给它一个组索引q[a[var1]] = j;
. 所以这里所有的访问都是线性的,因为我们使用元素直接访问一个键。因此,不会为每个元素一次又一次地分解一个组,因此时间更短。我的第一种方法是基于我自己的一个问题(我在第一行中提到过),它是更复杂的处理但更短的数据集。但这需要一个更简单直接的逻辑。