![한 열의 여러 값을 상수로 나누는 방법은 무엇입니까?](https://linux55.com/image/187638/%ED%95%9C%20%EC%97%B4%EC%9D%98%20%EC%97%AC%EB%9F%AC%20%EA%B0%92%EC%9D%84%20%EC%83%81%EC%88%98%EB%A1%9C%20%EB%82%98%EB%88%84%EB%8A%94%20%EB%B0%A9%EB%B2%95%EC%9D%80%20%EB%AC%B4%EC%97%87%EC%9E%85%EB%8B%88%EA%B9%8C%3F.png)
두 열의 값을 어떤 상수로 나누려고 합니다. 그러나 각 열에는 콜론으로 구분된 여러 값이 있습니다. 파일이 매우 큽니다(24개 파일, 각각 2~3GB). 예를 들어 내 파일의 레이아웃은 다음과 같습니다.
1 18 N 112:0:0:0:0:0 126:0:0:0:0:0 19:0:0:0:0:0 20:0:0:0:0:0
1 19 N 0:0:114:0:0:0 0:0:136:0:0:0 0:0:18:0:0:0 0:0:19:0:0:0
1 20 N 0:112:0:0:0:7 0:125:0:0:0:20 0:16:0:0:0:3 0:13:0:0:0:5
출력이 다음과 같기를 원합니다.
1 18 N 56:0:0:0:0:0 63:0:0:0:0:0 19:0:0:0:0:0 20:0:0:0:0:0
1 19 N 0:0:57:0:0:0 0:0:68:0:0:0 0:0:18:0:0:0 0:0:19:0:0:0
1 20 N 0:56:0:0:0:3.5 0:62.5:0:0:0:10 0:16:0:0:0:3 0:13:0:0:0:5
답변1
(@berndbausch의 사용법 아이디어 반복 split
) awk에는 배열을 다시 문자열로 평면화하는 기본 제공 방법이 없기 때문에 이것은 완전히 간단하지 않습니다. 우리는 printf를 사용해야 하며 그 결과 awk는 출력을 잘 정렬하는 방법을 잊어버립니다.
하지만 작동합니다.
#! /usr/bin/gawk -f
function print_div2(arr) {
split(arr, a, ":")
printf(" %d", a[1]/2)
delete a[1]
for(i in a) printf(":%d", a[i]/2)
}
{
ORS=""
print $1, $2, $3 " "
print_div2($4)
print " "
print_div2($5)
print " "
ORS="\n"
print $6, $7
}
print
참고: ORS는 각 레코드를 처리할 때까지 줄 바꿈을 억제하는 데 사용됩니다 . 필드 4와 5를 print_div2 함수에 할당합니다. 이 함수는 레코드를 배열로 분할하고 각 항목의 절반을 인쇄합니다.
파일에 넣고 실행 가능으로 표시하십시오. 사용 예:
$ ./process.awk data.txt
1 18 N 56:0:0:0:0:0 63:0:0:0:0:0 19:0:0:0:0:0 20:0:0:0:0:0
1 19 N 0:0:57:0:0:0 0:0:68:0:0:0 0:0:18:0:0:0 0:0:19:0:0:0
1 20 N 0:56:0:0:0:3 0:62:0:0:0:10 0:16:0:0:0:3 0:13:0:0:0:5
다음 명령을 사용하여 깔끔한 열 정렬을 복원할 수 있습니다 column
.
$ ./process.awk data.txt | column -t
1 18 N 56:0:0:0:0:0 63:0:0:0:0:0 19:0:0:0:0:0 20:0:0:0:0:0
1 19 N 0:0:57:0:0:0 0:0:68:0:0:0 0:0:18:0:0:0 0:0:19:0:0:0
1 20 N 0:56:0:0:0:3 0:62:0:0:0:10 0:16:0:0:0:3 0:13:0:0:0:5
답변2
awk '
function dyd(col, n){
split(col, t, ":");
sep=":";
return t[1]/n sep t[2]/n sep t[3]/n sep t[4]/n sep t[5]/n sep t[6]/n;
};
{ $4=dyd($4, 2); $5=dyd($5, 2); }1' infile |column -t