编辑:为清晰起见对其进行了编辑,并使示例文件最小化且更具可重复性,以便于帮助。谢谢!
我有超过 1000 行的文件。每个文件都使用相同数量的行进行格式化。的格式有 3 个“标题行”,1000+ 行值(正负数,后有 6 个小数位),然后是 13 个“尾行”。行的格式可以在下面看到。在我的真实文件中,在某些行上,我想要不同的命令,例如从行中打印文本,对实际数据取平均值,复制文本的行和数据的平均值以及日期和时间的平均值。
这是一个大纲或各种长文件,其中包含关于每行目标的一些注释。
下面的大纲是一个 dbriavated 示例。包含数据的行(示例中的第 4-9 行)实际上是真实文件中的第 4-1436 行。那么大纲中的第 10 行就是实际文件中的第 1437 行。(希望这是有道理的)。数据线可以包含负数或正数,范围从 -100 到 +5000。
ABCDEFGH # Line 1... print text into output file (same on across all files)
1 # Line 2... Take average of values across all the files in this line
2048 # Line 3... Take average of values across all the files in this line
8.123456 # Line 4... Take average of values across all the files in this line (could be positive or negative)
5.123456 # Line 5... Take average of values across all the files in this line (could be positive or negative)
5.654321 # Line 6... Take average of values across all the files in this line (could be positive or negative)
4.654321 # Line 7... Take average of values across all the files in this line (could be positive or negative)
9.654321 # Line 8... Take average of values across all the files in this line (could be positive or negative)
1.654321 # Line 9... Take average of values across all the files in this line (could be positive or negative)
90.00 # Line 10... Check and make sure value in this line across print if same
Sprite # Line 11... check and see if text is same across all values and print if same
cats10 # Line 12... check and see if text is same across all values and print if same
07/02/20 # Line 13... See below for explantion on next 3 lines
08:32 # Line 14...
08:32 # Line 15...
290.000000 # Line 16... average across all files on this line
10.750000 # Line 17... average across all files on this line
SCANS23 # Line 18... output should be SCANS "average of values"
INT_TIME57500 # Line 19... output should be INT_TIME "sum of values"
SITE northpole # Line 20...Check if all lines are same if so print line
LONGITUDE -147.850037 # Line 21... Output should be LONGITUDE "average"
LATITUDE 64.859375 # Line 22... Output should be LONGITUDE "average"
第 13 行是数据的来源日期,第 14 行是开始时间和结束时间。可能使用某种日期到十进制命令..有没有办法取日期的平均值?如果一个数据是在 2020 年 7 月 2 日获取的,而另一个数据是在 2018 年 7 月 2 日获取的,那么输出可以是 19 年 7 月 2 日吗?时间的平均值也会被考虑在内。
我认为一些扩展的三元运算符可能是一条路径,但是使用这么多不同的情况根本不起作用。
awk -F: '
FNR==1 { c++ };
/^LATITUDE/ { a[FNR] += $6 };
/^LONGITUDE/ { a[FNR] += $5 };
/^SITE/ { a[FNR] += $4 };
/^INT_TIME/ { a[FNR] += $3 };
/^SCANS/ { a[FNR] += $2 };
/^[+-]?([0-9]*[.])?[0-9]+$/ { a[FNR] += $1 };
END {
for (i in a) {
printf (i==22 ? "LATITUDE%f":
i==21 ? "LONGITUDE%2.3f":
i==20 ? "SITE%2.3f":
i==19 ? "INT_TIME%2.3f":
i==18 ? "SCANS%2.3f": "%f") "\n", a[i] / c
}
}' /home/test/test1.* > /home/average
假定所有示例文件都在其中,/home/test/aaaaaa-bbbb-cc10dddd-L1-2020070119*-01.std
并希望“平均”文件输出/home/dir/aaaaaa-bbbb-cc10dddd-L1-2020070119-01.std
格式为 /aaaaaa-bbbb-cc10-dddd-L1-"year""month""day""hour"-"elevation number “.std
输入文件于 2020 年 1 月 7 日 19 小时在海拔 1 处拍摄:
/home/dir/dir2/aaaaaa-bbbb-cc10dddd-L1-202007011918-01.std
/home/dir/dir2/aaaaaa-bbbb-cc10dddd-L1-202007011929-01.std
/home/dir/dir2/aaaaaa-bbbb-cc10dddd-L1-202007011941-01.std
/home/dir/dir2/aaaaaa-bbbb-cc10dddd-L1-202007011953-01.std
输出文件将是
/home/dir/aaaaaa-bbbb-cc10dddd-L1-2020070119-01.std
/home/dir/dir2/aaaaaa-bbbb-cc10dddd-L1-202007011918-01.std
ABCDEFGH
1
2048
-3.249389
-4.544701
5.822962
2.372011
-17.937092
20.000408
5.00
Sprite
cats10
07/01/20
19:18
19:18
290.000000
10.690000
SCANS23
INT_TIME57500
SITE northpole
LONGITUDE -147.850037
LATITUDE 64.859375
/home/dir/dir2/aaaaaa-bbbb-cc10dddd-L1-202007011929-01.std
ABCDEFGH
1
2048
-6.369022
-4.957337
-2.715081
1.766033
-20.002853
21.522350
5.00
Avantes
buoy10
07/01/20
19:29
19:29
290.000000
10.310000
SCANS23
INT_TIME57500
SITE giroof
LONGITUDE -147.850037
LATITUDE 64.859375
/home/dir/dir2/aaaaaa-bbbb-cc10dddd-L1-202007011926-01.std
ABCDEFGH
1
2048
2.961413
-14.236549
19.784035
2.711583
-18.305300
9.369226
5.00
Avantes
buoy10
07/02/20
19:26
19:26
290.000000
10.310000
SCANS23
INT_TIME57500
SITE giroof
LONGITUDE -147.850037
LATITUDE 64.859375
这可能接近您需要的,将
paste
(希望不是太多)输入文件放入awk
,关闭任何locale
影响:这有点笨拙,因为它通过行号检测“特殊处理”行,尤其是。日期/时间,但它似乎做了所要求的。我们需要预先计算行数并通过变量传递
wc - l
输出,awk
假设所有文件都具有相同的长度。可能还有其他/更好的方法。对于日期/时间计算:对于每次发生的事件都运行一个外部命令,这非常耗费资源date
,最重要的是,并非在所有操作系统版本上都可用。它适用于我的 linux 系统,但我愿意接受更好的想法。这可能是您正在寻找的,在日期平均计算中使用 GNU awk 作为时间函数并假设您的时区是 UTC 并且您的所有日期都是本世纪并且您没有任何空输入行:
如果日期在 2 次之间发生变化,时间计算会变得更有趣,但您通常无法在数据中表示它,所以我将其留作练习(提示:如果结束时间小于开始时间时间和你的间隔永远不能超过 24 小时,那么你知道你已经过了一天,所以可以将 24 小时添加到结束时间 - 如果间隔可以超过 24 小时,那么你就不走运了)。