我的问题如下: 我有一个格式化的文本文件:
12 apple
78 orange
12 prune
12 prune
78 berries
78 cake
我需要的是以表格形式重新分配值:
12 apple, prune
78 orange, berries, cake
我使用awk {sbj=$2","; a[$1]=a[$1]sbj}END{for (i in a) print i, a[i]}
做到了
但问题是现在我有了这个文件,格式为:
12 apple one
78 orange one
12 prune two
12 prune two
78 berries two
78 cake two
欲望输出是:
12 apple one
78 orange one
12 prune two
78 berries, cake two
我试图混合awk和bash,但它没有帮助。我现在能做的唯一选择是将每个系列("一个","两个")存储到单独的文件中,并使用上面的代码单独处理它们,然后将所有数组汇总到一份文件。但这是一个笨重而笨拙的解决方案。有没有选项让它在同一个文件中? 谢谢你的任何提示。
答案 0 :(得分:4)
$ cat tst.awk
NF {
if (!seen[$1,$2]++) {
arr[$1] = ($1 in arr ? arr[$1] "," OFS : "") $2
sfx[$1] = $3
}
next
}
{ prt() }
END { prt() }
function prt( i) {
for (i in arr) {
print i, arr[i], sfx[i]
}
print ""
delete sfx
delete arr
delete seen
}
$ awk -f tst.awk file
12 apple one
78 orange one
12 prune two
78 berries, cake two
请注意,上面将以in
运算符的随机顺序打印输出行 - 如果要保留原始输入顺序,则在保存值时需要额外的步骤。然而,它将按照它们在输入中出现的顺序打印块和$ 2值。
答案 1 :(得分:1)
使用GNU awk,您可以使用多维数组:
foo.awk:
!NF{next} # Skip empty lines
{a[$3][$1]=a[$3][$1]" "$2}
END{
for(i in a){
for(ii in a[i]){
print ii" "a[i][ii]" "i
}
print ""
}
}
像以下一样运行:
gawk -f foo.awk input.file
我需要提一下上述解决方案有一个缺点,除了它只适用于gawk
:输出不保证按顺序排列。那是因为for(i in a)
默认不保证任何订单。 gawk
支持一个特殊的数组变量PROCINFO
,可用于强制对数组进行单独排序:
foo.awk:
BEGIN {
PROCINFO["sorted_in"] = "@ind_str_asc"
}
!NF{next} # Skip empty lines
{a[$3][$1]=a[$3][$1]" "$2}
END{
for(i in a){
for(ii in a[i]){
print ii" "a[i][ii]" "i
}
print ""
}
}