我有两个名为f1和f2的文件夹。这些文件夹包含300个文本文件,包含2列。文件内容如下所示。我想计算第二列的平均值。两个文件夹中的文件名相同。
file1 in f1 folder
54 6
55 10
57 5
file2 in f1 folder
24 8
28 12
file1 in f2 folder
34 3
22 8
file2 in f2 folder
24 8
28 13
输出
folder1 folder2
file1 21/3= 7 11/2=5.5
file2 20/2=10 21/2=10.5
-- -- --
-- -- --
file300 -- --
total mean of folder1 = sum of the means/3oo
total mean of folder2 = sum of the means/3oo
答案 0 :(得分:2)
我用两个awk
脚本来做。 (最初,我在中间有一个sort
阶段,但这实际上并不是必需的。但是,我认为两个脚本可能比尝试将它们合并为一个更容易。如果其他人这样做,那么全部都在一个'并且它是可理解的,然后选择他们的解决方案。)
这是基于问题中显示的4个文件。命令行中列出了文件的名称,但顺序无关紧要。该代码假定文件名中只有一个斜杠,文件名中没有空格等。
$ awk -f summary1.awk f?/* | awk -f summary2.awk
file1 21/3 = 7.000 11/2 = 5.500
file2 20/2 = 10.000 21/2 = 10.500
total mean of f1 = 17/2 = 8.500
total mean of f2 = 16/2 = 8.000
function print_data(file, sum, count) {
sub("/", " ", file);
print file, sum, count;
}
oldfile != FILENAME { if (count > 0) { print_data(oldfile, sum, count); }
count = 0; sum = 0; oldfile = FILENAME
}
{ count++; sum += $2 }
END { print_data(oldfile, sum, count) }
依次处理每个文件,对第2列中的值求和并计算行数。它打印出文件夹名称,文件名,总和和计数。
{
sum[$2,$1] = $3
cnt[$2,$1] = $4
if (file[$2]++ == 0) file_list[n1++] = $2
if (fold[$1]++ == 0) fold_list[n2++] = $1
}
END { for (i = 0; i < n1; i++)
{
printf("%-20s", file_list[i])
name = file_list[i]
for (j = 0; j < n2; j++)
{
folder = fold_list[j]
s = sum[name,folder]
n = cnt[name,folder]
a = (s + 0.0) / n
printf(" %6d/%-3d = %10.3f", s, n, a)
gsum[folder] += a
}
printf("\n")
}
for (i = 0; i < n2; i++)
{
folder = fold_list[i]
s = gsum[folder]
n = n1;
a = (s + 0.0) / n
printf("total mean of %-6s = %6d/%-3d = %10.3f\n", folder, s, n, a)
}
}
file
关联数组跟踪对文件名的引用。 file_list
数组按文件名的顺序保存文件名。同样,fold
关联数组跟踪文件夹名称,fold_list
数组按照它们出现的顺序跟踪文件夹名称。如果您使用为第一个命令提供名称的顺序执行了一些奇怪的操作,则可能需要在两个sort
命令之间插入awk
命令,例如sort -k2,2 -k1,1
。< / p>
sum
关联数组包含给定文件名和文件夹名的总和。 cnt
关联数组包含给定文件名和文件夹名的计数。
报告的END
部分有两个主循环(尽管第一个循环包含嵌套循环)。第一个主循环按所示顺序处理文件,生成一行,每行包含一个条目。它还会累积文件夹名称的平均值。
第二个主循环生成每个文件夹的“总平均值”数据。我不确定统计数据是否有意义(不应该将folder1的总体平均值作为folder1中值的总和除以条目数,或者41/5 = 8.2而不是17/2或8.5?),但计算完成了我认为问题的要求(平均值/文件数量,在问题中写成300)。
答案 1 :(得分:0)
在grep的帮助下:
grep '[0-9]' folder[12]/* | awk '
{
split($0,b,":");
f=b[1]; split(f,c,"/"); d=c[1]; f=c[2];
s[f][d]+=$2; n[f][d]++; nn[d]++;}
END{
for (f in s) {
printf("%-10s", f);
for (d in s[f]) {
a=s[f][d] / n[f][d];
printf(" %6.2f ", a);
p[d] += a;
}
printf("\n");
}
for (d in p) {
printf("total mean %-8s = %8.2f\n", d, p[d]/nn[d]);
}
}'