我有一个如下所示的 txt 文件(这张图片来自它的 .csv 版本)。我喜欢做的是取月份的平均值(从第 7 列到第 10 列)并将其导出到新列。但它只给了我一个平均数。
OBSERVATORY,Abbreviations,COUNTRY,ALTITUDE(m),LONGITUDE(deg),LATITUDE (deg),January,February,March,April,May,June,July,August,September,October,November,December
Beverly-Begg Observatory Dunedin,,New Zealand,140,170.49,-45.8644,89.93,86.84,85.26,88.22,89.36,89.8,88.52,90.42,88.74,89.06,91.16,91.36
Aorangi Iti Observatory Lake Tekapo,,New Zealand,718,170.473,-44.0082,63.92,60.44,58.63,65.68,75.97,85.7,84.85,83.7,76.34,70.56,70.2,70.4
Mount John Observatory Lake Tekapo,,New Zealand,945,170.465,-43.9874,62.4,60.91,58.98,67.15,79.45,85.24,86.93,84.96,77.1,72.0,70.9,71.85
我的代码是这样的:
awk '{ sum += $5 + $6 + $7 + $8 + $9 + $10 + $11 + $12 + $13 + $14
+ $15 } END { print sum / (NR * 18) }' observatory_1.txt > observatory_3.txt
output: 0.104394
我想创建一个txt文件夹,如下所示:
OBSERVATORY, Abbreviations, COUNTRY, ALTITUDE(m), LONGITUDE(deg), LATITUDE (deg), MEAN
Beverly-Begg Observatory Dunedin, , New Zealand, 140, 170, 490, -45,8644, 89,05583333
任何建议将不胜感激。
答案1
您的脚本对每个输入行中的一堆列进行求和,然后在读取所有输入行后,END 块将打印一个输出行...因此它在生成任何输出之前处理整个文件。
您应该做的是单独处理每个输入行。
您的列号似乎也有偏差 - 例如,为什么您要在平均值计算中包括海拔、经度和纬度?我假设您实际上想要第 7 至 19 列(1 月至 12 月)的平均值。
不管怎样,你可能想要更多这样的东西:
awk -F, -v OFS=, '
NR == 1 { print $1, $2, $3, $4, $5, $6, "MEAN" }
NR > 1 {
sum = 0;
for (i=7; i<=19; i++) { sum += $i }
print $1, $2, $3, $4, $5, $6, (sum / 12)
}' observatory_1.txt > observatory_3.txt
这将产生如下输出:
OBSERVATORY,Abbreviations,COUNTRY,ALTITUDE(m),LONGITUDE(deg),LATITUDE (deg),MEAN
Beverly-Begg Observatory Dunedin,,New Zealand,140,170.49,-45.8644,89.0558
Aorangi Iti Observatory Lake Tekapo,,New Zealand,718,170.473,-44.0082,72.1992
Mount John Observatory Lake Tekapo,,New Zealand,945,170.465,-43.9874,73.1558
这可能不完全是您想要的,但它应该是朝着正确方向迈出的一步。
答案2
使用乐(以前称为 Perl_6)
raku -e 'put get.split(",")[0..5].join(",") ~ ",MEAN"; \
for lines() {my @a = .split(","); \
put (@a[0...5].join(",") ~ "," ~ @a.[6..*].sum / @a.[6..*].elems)};'
或者
raku -ne 'state $i=0; ++$i; my @a = .split(","); $i == 1 \
?? put @a.[0..5].join(",") ~ ",MEAN" \
!! put (@a[0...5].join(",") ~ "," ~ @a.[6..*].sum / @a.[6..*].elems);'
输入示例:
OBSERVATORY,Abbreviations,COUNTRY,ALTITUDE(m),LONGITUDE(deg),LATITUDE (deg),January,February,March,April,May,June,July,August,September,October,November,December
Beverly-Begg Observatory Dunedin,,New Zealand,140,170.49,-45.8644,89.93,86.84,85.26,88.22,89.36,89.8,88.52,90.42,88.74,89.06,91.16,91.36
Aorangi Iti Observatory Lake Tekapo,,New Zealand,718,170.473,-44.0082,63.92,60.44,58.63,65.68,75.97,85.7,84.85,83.7,76.34,70.56,70.2,70.4
Mount John Observatory Lake Tekapo,,New Zealand,945,170.465,-43.9874,62.4,60.91,58.98,67.15,79.45,85.24,86.93,84.96,77.1,72.0,70.9,71.85
示例输出(对于上面的两种代码解决方案):
OBSERVATORY,Abbreviations,COUNTRY,ALTITUDE(m),LONGITUDE(deg),LATITUDE (deg),MEAN
Beverly-Begg Observatory Dunedin,,New Zealand,140,170.49,-45.8644,89.055833
Aorangi Iti Observatory Lake Tekapo,,New Zealand,718,170.473,-44.0082,72.199167
Mount John Observatory Lake Tekapo,,New Zealand,945,170.465,-43.9874,73.155833
简要解释第一个答案:get
标题行、split
逗号和put
前 6 列,然后MEAN
使用.split(",")[0..5].join(",") ~ ",MEAN"
. (ICYMI,~
波形符用于连接 Raku 中的字符串)。
现在,在第二行(第一个数据行)处使用逐行读取游标,for lines()
读取输入(逐行),逗号split
上的 s","
并将元素存储在@a
数组中。前六列@a[0..5]
是put
用 计算的平均值@a.[6..*].sum / @a.[6..*].elems
。
请注意,您可能可以使用 硬编码列索引@a.[6..17].sum / @a.[6..17].elems
,如果它始终是 12 列,您可以@a.[6..17].sum / 12
这样做。最后, @a.[6..17].map(*.chars > 0).sum
如果您需要调整缺失值,请用作分母。
答案3
我们可以使用 GNU 来做到这一点直流电RPN 计算器。但在此之前我们需要这 3 个转换,这是使用珀尔:
- 将非数字字段括在 [] 中
- 数字字段的负号更改为 _
- 将逗号更改为空格。
perl -F, -lane 'my $i;
print join " ", map {
$i++ < ($.>1?3:@F) ? qq([$_]) : s/^-/_/r;
} @F;
' file |
dc -e "
#### macros definitions
[q]sq [44an]sz # OFS set to comma
[+z7<a]sa # aum last 12 entries
[SMz0<b]sb # shunt remaining to M
[LMnz6>zzz6>c]sc # print LIFO M
[?z0=q
lax #sum last 12 cols
lbx #store all in stack M
lcx #print
LM12.0/p #orint average
cz0=?]s?
###> header processing
?[
[4k]s0 [XrX=0z6<1]s1
l1x lbx lcx [MEAN]pc
]x
##> non header lines
l?x
"
OBSERVATORY,Abbreviations,COUNTRY,ALTITUDE(m),LONGITUDE(deg),LATITUDE (deg),MEAN
Beverly-Begg Observatory Dunedin,,New Zealand,140,170.49,-45.8644,89.0558
Aorangi Iti Observatory Lake Tekapo,,New Zealand,718,170.473,-44.0082,72.1991
Mount John Observatory Lake Tekapo,,New Zealand,945,170.465,-43.9874,73.1558