Câu trả lời:
Sử dụng 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
Sử dụng numsum
cho nhiệm vụ đó và tách biệt giữa xử lý dữ liệu và xuất kết quả.
Cài đặt num-utils
, chúng tôi cầnnumsum
sudo apt-get install num-utils
Và bắt đầu với
numsum -c <your_file_name>
Thí dụ
$ cat "File A"
1 2
2 3
4 5 6
1 1 1 5
$ numsum -c "File A"
8 11 7 5
hoặc với định dạng mong muốn của bạn:
$ 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
từ man numsum
-c Print out the sum of each column.
ví dụ từ 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
#!/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 ))
, vv Ngoài ra, echo "..."
an toàn hơn, cũng nhưwhile IFS= read -r ...
echo
an toàn khi được sử dụng theo cách đó để lặp lại các số, $IFS
mặc định ở khoảng trắng và chúng được dự kiến là số, do đó không cần phải xử lý dấu gạch chéo ngược. Nhược điểm duy nhất của câu trả lời này là cần biết số lượng cột trước khi thực hiện.
echo "[...]"
để in chính xác những gì bạn không muốn xuất không có ý nghĩa.
echo $var
và while read a b c
, nó hoạt động ở đây. Tuy nhiên, bạn sẽ quen với việc viết nó theo cách yếu và một ngày nào đó bạn sẽ gặp phải những lỗi lạ trong khi xử lý một tệp phức tạp hơn. Sau đó, bạn sẽ nhận thấy trích dẫn các biến và sử dụng while IFS= read -r ...
là an toàn hơn và sẽ nói "oh yeah fedorqui đã đúng, tôi hy vọng tôi có thể có anh ấy để ôm anh ấy để thể hiện lòng biết ơn!".
Đánh giá bằng các bình luận cho câu trả lời của riêng bạn, bạn chỉ muốn tổng của một cột tại một thời điểm. Nếu vậy, đây là một cách không hay để làm điều đó:
cut -d' ' -f3 FileA | grep . | paste -s -d+ | bc
nơi bạn sẽ thay thế 3
bằng số cột bạn quan tâm.
Đây là một cách tiếp cận kịch bản Perl một lớp. Điều này phụ thuộc vào việc sử dụng -a
cờ cho phép tự động phân tách dòng đang đọc với -n
cờ thành mảng @F
. Tất cả những gì chúng ta phải làm là lặp lại các mục đó và thêm chúng vào chỉ mục tương ứng của chúng trong $sum
mảng, do đó, hiệu quả của từng mục mảng là tổng cho mỗi cột tương ứng. Cuối cùng, chúng tôi in kết quả trong END
khối mã.
$ perl -lane '$j=0;foreach $i (@F){$sum[$j]+=$i; $j+=1;}; END{print join("\n",@sum)} ' input.txt
8
11
7
5
Ngoài ra, đây là một cách tiếp cận kịch bản Perl đầy đủ. Nó dựa vào việc chia từng dòng thành mảng và lặp lại qua từng mục trong mảng đó thêm từng số vào sở hữu tương ứng của chúng trong @sums
mảng. Kịch bản in ra từng dòng, sau đó tạo báo cáo cho từng cột. In từng dòng có thể được loại bỏ bằng cách thêm #
trướcprintf("%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);
Cách sử dụng rất đơn giản chmod +x ./sum_columns.pl && ./sum_columns.pl input.txt
. Ví dụ:
$ ./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
Một giải pháp đơn giản:
awk '{sum += $i} END {print sum}' file
Thay thế i bằng số cột ví dụ cột1:
awk '{sum += $1} END {print sum}' file
đầu ra là:
8