여러 파일의 n번째 행 평균을 하나의 평균 마스터 파일로 병합

여러 파일의 n번째 행 평균을 하나의 평균 마스터 파일로 병합

8줄의 값과 텍스트가 포함된 파일이 3개 있습니다. 세 파일 모두에서 각 줄의 평균을 구하고 해당 평균으로 새 파일을 인쇄하려고 합니다. 다음은 이름 형식이 동일한 세 개의 샘플 파일입니다: 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줄의 데이터에 적합했지만 실제 데이터에는 40개가 넘는 파일 이름이 포함된 2000줄이 넘었습니다.

편집: 그래서 인쇄하려는 숫자를 제어하는 ​​방법과 부동 소수점과 더 잘 일치하도록 정규식을 편집하는 방법을 이해할 수 있습니다.

(이 질문을 다른 질문으로 만들고 이 질문을 삭제해야 하는지 알려주세요!)

내 실제 데이터에는 텍스트와 평균을 구하려는 값이 포함된 다른 행이 많이 있습니다. 추가 문자열을 만들려고 시도했지만 더 혼란스러워졌습니다. 내 실제 파일의 특정 라인에서는 라인의 텍스트 인쇄, 실제 데이터 평균화, 텍스트와 데이터의 평균으로 라인 복사, 날짜 및 시간 평균화와 같은 다양한 명령을 원합니다.

아래는 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배열에 대한 인덱스로 사용됩니다. 행에 숫자만 포함된 경우 행의 첫 번째(유일한) 필드가 행의 배열 요소에 추가됩니다. string 으로 시작하는 경우 Lat:두 번째 필드가 추가됩니다.

모든 입력 파일을 읽고 처리한 후 END 블록이 실행됩니다. 이는 배열을 반복하여 각 요소의 합계를 파일 수로 나눈 값을 인쇄합니다. 8행을 제외한 모든 행은 정수로만 인쇄됩니다.

8행의 경우 정수 앞에 문자열이 붙습니다 Lat:. 스크립트는 이를 달성하기 위해 awk의 삼항 연산자를 사용합니다.condition ? result_if_true : result_if_false

관련 정보