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==1
FNR
또한 배열을 사용하여 a
각 입력 행의 누적 합계를 저장하며 FNR
배열에 대한 인덱스로 사용됩니다. 행에 숫자만 포함된 경우 행의 첫 번째(유일한) 필드가 행의 배열 요소에 추가됩니다. string 으로 시작하는 경우 Lat:
두 번째 필드가 추가됩니다.
모든 입력 파일을 읽고 처리한 후 END 블록이 실행됩니다. 이는 배열을 반복하여 각 요소의 합계를 파일 수로 나눈 값을 인쇄합니다. 8행을 제외한 모든 행은 정수로만 인쇄됩니다.
8행의 경우 정수 앞에 문자열이 붙습니다 Lat:
. 스크립트는 이를 달성하기 위해 awk의 삼항 연산자를 사용합니다.condition ? result_if_true : result_if_false