awk를 사용하여 행의 나머지 부분을 기준으로 첫 번째 열의 값을 합산합니다.

awk를 사용하여 행의 나머지 부분을 기준으로 첫 번째 열의 값을 합산합니다.

여러 개의 중복 행이 있는 파일이 있는데 첫 번째 열만 다릅니다.

원본 파일:

2 A 3 rr 44 5 t y uuu 8
3 A 3 rr 44 5 t y uuu 8
0 B f 1
1 C 6 5 55 yy 7 4 3 4-5 tt efvho 44 3 5 gg 5  4 t rr 33
5 C 6 5 55 yy 7 4 3 4-5 tt efvho 44 3 5 gg 5  4 t rr 33
5 C 6 5 55 yy 7 4 3 4-5 tt efvho 44 3 5 gg 5  4 t rr 33
3 D tt v 44 f1 p
1 D tt v 44 f1 p

내가 원하는 것은 중복을 제거하고 첫 번째 열의 값을 합산하는 것입니다.

원하는 출력:

5 A 3 rr 44 5 t y uuu 8
0 B f 1
11 C 6 5 55 yy 7 4 3 4-5 tt efvho 44 3 5 gg 5  4 t rr 33
4 D tt v 44 f1 p

이 스크립트는 내가 하려는 작업과 매우 유사합니다.

awk  '{a[$2]+=$1}END{for(i in a)print a[i] , i |"sort"}' file

다음과 같은 출력을 제공합니다.

5 A 
0 B 
11 C 
4 D 

이 스크립트의 첫 번째 열을 제외한 모든 열에 $2를 변경할 수 있는 방법이 있나요?

답변1

이것은 작동하지만 행의 순서를 유지하지 않습니다.

awk '{v=$1; $1=""; s[$0]=s[$0]+v} END {for (r in s) { printf "%s%s\n",s[r],r }}' file
  • 첫 번째 필드를 변수에 저장한 다음 지웁니다.
  • (비워진) 행이 있는 배열을 $1키로 저장하고 저장된 합계를 $1값으로 저장합니다.
  • 마지막으로 배열을 인쇄합니다. printf삭제할 수 없고 비어 있을 뿐이므로 추가 공간을 피하기 위해 사용합니다 $1.

| sort -k2두 번째 열을 정렬하려면 추가하세요 .

산출:

5 A 3 rr 44 5 t y uuu 8
0 B f 1
11 C 6 5 55 yy 7 4 3 4-5 tt efvho 44 3 5 gg 5 4 t rr 33
4 D tt v 44 f1 p

답변2

사용 datamashawk:

중복 행은 첫 번째 열에서만 다르기 때문에 이 datamash명령이 작동합니다.

$ datamash -s -t' ' groupby 2 sum 1 --full <file | 
awk '{$1=$NF; NF -= 1}1'

답변3

한 번에 한 라인만 메모리에 저장하고 awk를 사용하여 출력에서 ​​입력 순서를 재현합니다.

$ cat tst.awk
{
    currKey = $0
    sub(/[^[:space:]]+ /,"",currKey)
}
currKey != prevKey {
    if ( NR > 1 ) {
        print prev0
    }
    prevKey = currKey
    prev1 = 0
}
{
    $1 += prev1
    prev1 = $1
    prev0 = $0
}
END {
    print prev0
}

$ awk -f tst.awk file
5 A 3 rr 44 5 t y uuu 8
0 B f 1
11 C 6 5 55 yy 7 4 3 4-5 tt efvho 44 3 5 gg 5 4 t rr 33
4 D tt v 44 f1 p

위의 내용은 중복 행이 함께 그룹화되어 있다고 가정합니다. 그렇지 않은 경우 를 실행하십시오 sort -k2 file | awk '...'.

관련 정보