我的目标是进入一个子目录,称之为 SUB,其中有许多文本文件,每个文件有 5 列,并且行数始终相同。我想要一个大的“总和”文件,该文件将 2-5 中的所有列相加,保留第一列,然后输出该文件。如果我知道文件数量很小,可以按如下方式完成:
cd SUB
numfiles=(*)
numfiles=${#numfiles[@]}
if [ $numfiles = 1 ]
then
paste * | awk '{print $1, $2, $3, $4, $5}' > sum
fi
if [ $numfiles = 2 ]
then
paste * | awk '{print $1, ($2+$7), ($3+$8), ($4+$9), ($5+$10)}' > sum
fi
然而,由于 SUB 中的文件数量可能在 1 到 100 之间,因此这是一种麻烦的方法。感谢您的帮助!
PS 新“sum”文件的格式应该与输入文本文件的格式相同,看起来都一样。例如,如果 SUB 包含两个带有条目的文件
1 2 3 4 5
2 2 3 4 5
和
1 4 2 7 1
2 2 5 1 9
那么“sum”文件应该是
1 6 5 11 6
2 4 8 5 14
答案1
awk '
NR==FNR {
# assuming column 1 is the same for all files, remember it.
# only need to do this for the first file
col1[FNR] = $1
}
{ for (i=2; i<=NF; i++) sum[FNR,i] += $i }
END {
for (i=1; i<=FNR; i++) {
printf "%s", col1[i]
for (j=2; j<=NF; j++) printf "%s%s", OFS, sum[i,j]
print ""
}
}
' file1 file2
1 6 5 11 6
2 4 8 5 14
应该与 nawk、gawk 和 mawk 一起工作。
答案2
干得好。这实际上使用gawk
而不是 vanilla awk
。如果您确实需要使用 trueawk
我认为您需要将h[x][y]
结构更改为类似h[x ";" y]
.
cd SUB
awk '
BEGIN { PROCINFO["sorted_in"] = "@ind_num_asc" }
{ h[FNR][1] = $1; for (n=2; n<=5; n++) { h[FNR][n] += $n } }
END { for (r in h) { print h[r][1], h[r][2], h[r][3], h[r][4], h[r][5] } }
' *
根据您的示例输入,它会提供您预期的输出。
我已PROCINFO
按照评论中的建议添加了设置。