将多个文件中第 n 行的平均值合并到一个平均主文件中

将多个文件中第 n 行的平均值合并到一个平均主文件中

我有 3 个文件,其中包含 8 行数值和文本。我试图取所有三个文件中每行的平均值,并用这些平均值打印一个新文件。下面是三个示例文件,名称格式均相同:testfile1.1、testfile1.2、testfile1.3

测试文件1.1

1
2048
8
5
5
4
9
Lat:1

测试文件1.2

1
2048
10
7
7
4
9
Lat:1

测试文件1.3

1
2048
3
6
3
4
6
Lat:7

我希望输出文件如下所示(取平均值后)

平均文件1

1
2048
7
6
5
4
8
Lat:3

希望这对我想做的事情有意义!

我尝试过使用 awk、sed 的不同组合,对于 3-4 行数据效果很好,但我的实际数据有 2000 多行,涉及 40 多个文件名

编辑:所以我能够理解如何控制我想要打印的数字以及如何编辑正则表达式以更好地匹配浮动小数。

(请告诉我是否应该将此作为另一个问题并删除此问题!)。

我的实际数据有很多其他行,其中包含文本以及我想要取平均值的值。我尝试创建额外的字符串,但后来变得更加困惑。在我的真实文件中,在某些行上,我想要不同的命令,例如从行打印文本、对实际数据取平均值、复制文本和数据平均值的行以及对日期和时间取平均值。

下面是 2 个文件的副本(每行都有注释,我想对它们做些什么)。

豆腐1.1

ABCDEFGH #print text into output file (same on both files)
1     # Take average of values across all the files in this line
2048  # Take average of values across all the files in this line
8     # Take average of values across all the files in this line
5     # Take average of values across all the files in this line
5     # Take average of values across all the files in this line
4     # Take average of values across all the files in this line
9.5   # Take average of values across all the files in this line
1     # Take average of values across all the files in this line
90.00  # Check and make sure value in this line across print if same
Sprite # check and see if text is same across all values and print if same
cats10   # check and see if text is same across all values and print if same
07/02/20 # See below for explantion on next 3 lines
08:32
08:32
290.000000 # average across all 3 files on this line
10.750000 # average across all 3 files on this line
SCANS23   # output should be SCANS "average of values"
INT_TIME57500 # output should be INT_TIME with sum of all values
SITE northpole   #Check if all lines are same if so print line
LONGITUDE -147.850037  # Output should be LONGITUDE%f
LATITUDE 64.859375     # Output should be LONGITUDE%f

第 13 行是数据的来源日期,第 14 行是开始时间和结束时间。可能使用某种日期到十进制命令..有没有办法取日期的平均值?如果一个数据是在 07/02/20 获取的,另一个数据是在 07/02/18 获取的,那么输出可以是 07/02/19 吗?时间的平均值也会被考虑在内。

豆腐1.2

ABCDEFGH #print text into output file (same on both files)
1     # Take average of values across all the files in this line
2048  # Take average of values across all the files in this line
10    # Take average of values across all the files in this line
7     # Take average of values across all the files in this line
7     # Take average of values across all the files in this line
4     # Take average of values across all the files in this line
8   # Take average of values across all the files in this line
1     # Take average of values across all the files in this line
90.00  # Check and make sure value in this line across print if same
Sprite # check and see if text is same across all values and print if same
cats10   # check and see if text is same across all values and print if same
07/02/20 # See below for explanation on next 3 lines
08:32
08:32
290.000000 # average across all 3 files on this line
10.750000 # average across all 3 files on this line
SCANS23   # output should be SCANS "average of values"
INT_TIME57500 # output should be INT_TIME with sum of all values
SITE northpole   #Check if all lines are same if so print line
LONGITUDE -147.850037  # Output should be LONGITUDE%f
LATITUDE 64.859375     # Output should be LONGITUDE%f

我厌倦了尝试在脚本中包含多个字符串起始值,但很快就变得非常混乱。

awk -F: '
  FNR==1     { c++ };
  /^LATITUDE/    { a[FNR] += $6 };
  /^SCANS/    { a[FNR] += $2 };
  /^[+-]?([0-9]*[.])?[0-9]+$/ { a[FNR] += $1 };

  END {
    for (i in a) {
      printf (i==22 ? "LATITUDE%f": i==18 ? "SCANS%2.3f": "%f") "\n", a[i] / c
    }
  }' tofu1.* > askforhelp

这给了我

$ more askforhelp

90.000000
LATITUDE0.000000
290.000000
10.750000
SCANS0.000
1.000000
2048.000000
6.333333
4.666667
5.000000
4.000000
7.833333
2.666667

我还尝试一次添加多个文本字符串,当我从这次尝试中完全没有输出时,我感到非常困惑。

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/lmdjeu/test/test1.* > /home/lmdjeu/test/askforhelp

答案1

$ awk -F: '
  FNR==1     { c++ };
  /^Lat:/    { a[FNR] += $2 };
  /^[0-9]+$/ { a[FNR] += $1 };

  END {
    for (i in a) {
      printf (i==8 ? "Lat:%i" : "%i") "\n", a[i] / c
    }
  }' Testfile1.* > Averagefile1

$ cat Averagefile1
1
2048
7
6
5
4
8
Lat:3

它使用变量c来计算已读入的文件数。每当读取 c文件的第一行 ( ) 时,该变量就会递增。是 awk 自动设置的输入记录(行号)计数器,每次读取输入文件时都会重置它。FNR==1FNR

它还使用一个数组a来存储每行输入的累积和——FNR用作数组的索引。如果该行仅包含数字,则该行上的第一个(也是唯一一个字段)将添加到该行的数组元素中。如果它以字符串 开头Lat:,则添加第二个字段。

读取并处理所有输入文件后,将执行 END 块。这会迭代数组,打印每个元素中的总和除以文件数。除第 8 行之外的所有行都仅打印为整数。

对于第 8 行,整数以字符串 为前缀Lat:。该脚本使用 awk 的三元运算符来实现此目的:condition ? result_if_true : result_if_false

相关内容