파일에서 각 열의 합계를 계산


9

공백 ''으로 구분 된 다른 수의 열이있는 파일에서 열의 합계를 계산하는 방법 예는 다음과 같은 필요성을 보여줍니다.

File A:

1 2 
2 3
4 5 6 
1 1 1 5

그러면 출력은 다음과 같습니다.

  • 열 1의 경우 (1 + 2 + 4 + 1) = 8
  • 2 열은 11
  • 3 열은 7
  • 열 4의 경우 5입니다

답변:


12

사용 awk

awk '{for (i=1;i<=NF;i++) sum[i]+=$i;}; END{for (i in sum) print "for column "i" is " sum[i];}' FileA
for column 1 is 8
for column 2 is 11
for column 3 is 7
for column 4 is 5

배열을 잘 사용하지만 합계를 세고 바로 인쇄하는 것으로 단순화 될 수 있다고 생각합니다.
Sergiy Kolodyazhnyy 2016 년

실제로 이것이 가장 좋은 대답입니다.
kos

5

numsum해당 작업에 사용 하고 데이터 처리를 분리하고 결과를 출력합니다.

설치 num-utils, 우리는 필요numsum

sudo apt-get install num-utils

그리고 시작

numsum -c <your_file_name>

$ cat "File A"
1 2 
2 3
4 5 6 
1 1 1 5

$ numsum -c "File A"
8 11 7 5

또는 원하는 형식으로 :

$ numsum -c "File A" | awk '{for(i=1;i<=NF;i++) {print "for column "i" is "$i}}'
for column 1 is 8
for column 2 is 11
for column 3 is 7
for column 4 is 5

...에서 man numsum

-c      Print out the sum of each column.

의 예 man numsum

EXAMPLES

   Add up the 1st, 2nd and 5th columns only.

       $ numsum -c -x 1,2,5 columns
       15 40 115

   Add up the rows of numbers of a file.

        $ numsum -r columns
        55
        60
        65
        70
        75

3
#!/bin/sh

while read a b c d; do
    col1=$((col1 + a))
    col2=$((col2 + b))
    col3=$((col3 + c))
    col4=$((col4 + d))
done < File_A

echo $col1 $col2 $col3 $col4

당신은 아마 (( col1 += a ))등등을 말할 수 있습니다 . 또한 echo "..."더 안전 할뿐만 아니라while IFS= read -r ...
fedorqui

@fedorqui echo는 숫자를 반향하는 방법, $IFS공백의 기본값 및 숫자가 될 것으로 예상되므로 백 슬래시를 처리 할 필요가 없습니다. 이 답변의 유일한 단점은 실행 이전의 열 수를 알아야한다는 것입니다.
kos

@kos 당신은 입력 파일이 어떻게 될 수 있는지 알 수 없습니다. OP가 숫자 만 언급 했음에도 불구하고 항상 더 나쁜 상황에 대비하는 것이 좋습니다. 파일 (데이터 스트림, 변수)을 한 줄씩 또는 필드별로 읽는 방법을 참조하십시오 . 장엄한 설명을 위해.
fedorqui

@fedorqui 자신의 진술에 따르면 이것이 논의의 여지가 없었습니다. 입력 파일에 숫자 이외의 것이 포함될 수 있다고 가정하면 뻔한 부분이 누락됩니다. 읽는 것이 숫자인지 확인하십시오. 문자열을 추가 echo "[...]"하고 출력하지 않으려는 것을 올바르게 인쇄하는 데 사용 하는 것은 의미가 없습니다.
kos

@kos 물론 말할 수도 echo $var있고 while read a b c여기서 작동합니다. 그러나 약한 방식으로 작성하는 데 익숙해지고 언젠가 더 복잡한 파일을 처리하는 동안 이상한 오류가 발생합니다. 그러면 변수를 인용하고 사용하는 while IFS= read -r ...것이 더 안전하다는 것을 알 수있을 것입니다. "아, 페 도르 퀴가 옳았습니다. 감사를 표하기 위해 그를 안아 줄 수 있기를 바랍니다."
fedorqui

3

자신의 답변에 대한 주석으로 판단하면 한 번에 한 열의 합계 만 원합니다. 그렇다면 다음과 같은 방법을 사용하십시오.

cut -d' ' -f3 FileA | grep . | paste -s -d+ | bc

여기서 당신 3이 관심있는 열 번호로 바꿀 것 입니다.


0

한 줄짜리 Perl 스크립트 접근 방식이 있습니다. 이것은 -a플래그를 사용하여 현재 읽기 행을 -n플래그로 배열에 자동 분할 할 수 있는 플래그 사용에 의존합니다 @F. 우리가해야 할 일은 해당 항목을 반복하고 $sum배열 의 해당 인덱스에 추가하기 때문에 각 배열 항목은 각 열의 합계입니다. 마지막으로 END코드 블록 내에 결과를 인쇄합니다 .

$ perl -lane '$j=0;foreach $i (@F){$sum[$j]+=$i; $j+=1;}; END{print join("\n",@sum)} ' input.txt                                                     
8
11
7
5

또는 전체 Perl 스크립트 접근 방식이 있습니다. 각 행을 배열로 분할하고 해당 배열의 각 항목을 반복하여 각 숫자를 배열의 해당 위치에 추가합니다 @sums. 스크립트는 각 줄을 인쇄 한 다음 각 열에 대한 보고서를 생성합니다. #전에 추가하여 각 줄의 인쇄를 제거 할 수 있습니다printf("%s",$line);

#!/usr/bin/env perl
use strict;
use warnings;

open(my $fh,"<",$ARGV[0]); 
my $i = 0;
my @sums;

while(my $line = <$fh>) { 
    printf("%s",$line);
    my @nums = split(" ",$line);
    my $j = 0;
    foreach my $num (@nums){
        $sums[$j] += $num;
        $j += 1;
    }

}

my $k = 0;
foreach my $sum (@sums){
    printf("- column %d sum: %d\n",$k,$sum);
    $k+=1;
}

close($fh);

사용법은 간단하다 chmod +x ./sum_columns.pl && ./sum_columns.pl input.txt. 예를 들면 다음과 같습니다.

$ ./sum_columns_2.pl input.txt                                                                                                                       
1 2 
2 3
4 5 6 
1 1 1 5
- column 0 sum: 8
- column 1 sum: 11
- column 2 sum: 7
- column 3 sum: 5

-2

간단한 해결책 :

awk '{sum += $i} END {print sum}' file

i를 열 번호 (예 : column1)로 바꾸십시오.

awk '{sum += $1} END {print sum}' file

출력은 다음과 같습니다

8

3
이것은 하나의 열만 가져옵니다. 자신의 사양을 충족하지 않습니다.
Oli

나는 모든 결과를 같은 명령으로 원한다고 말하지 않았다. 또한이 답변은 루프가 필요하고 완벽합니다.
Maythux

왜 downvoting?
Maythux
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.