2012-11-07 41 views
7

Tôi có 500 tệp có tên fort.1, fort.2 ... fort.500. Mỗi tập tin chứa dữ liệu 800 điểm như sau:tính trung bình sử dụng awk từ nhiều tệp

1 0,485
2 0,028
3 0,100
4 0,979
5 0,338
6 0,891
7 0,415
8 0,368
9 0,245
10 0.489

Tôi muốn lấy trung bình của mỗi dòng của cột thứ hai từ mỗi tệp. Nói cách khác, lấy trung bình của dòng thứ hai cột đầu tiên từ tất cả các tập tin và lưu trữ trong "output.file". Sau đó nhận được trung bình của cột thứ hai của dòng thứ hai và lưu trữ trong cùng một "output.file". Tôi đã thử với lệnh dán nhưng không nhận được những gì tôi muốn. Có cách nào để thực hiện trong AWK không?

Đánh giá cao sự trợ giúp. Cảm ơn

Trả lời

1

Sự hiểu biết của tôi: mỗi tệp là một tập hợp các phép đo tại một vị trí cụ thể. Bạn muốn tổng hợp các phép đo trên tất cả các vị trí, tính trung bình giá trị của cùng một hàng trong mỗi tệp vào một tệp mới.

Giả sử cột đầu tiên có thể được coi là một ID cho hàng (và có 800 phép đo trong một tập tin):

cat fort.* | awk ' 
BEGIN { 
    for (i = 1; i <= 800; i++) 
     total[i] = 0 
} 

{ total[$1] += $2 } 

END { 
    for (i = 1; i <= 800; i++) 
     print i, total[i]/500 
} 
' 

tiên, chúng ta khởi tạo một mảng để lưu trữ tổng cho một hàng trên tất cả các các tập tin.

Sau đó, chúng tôi lặp qua các tệp được ghép nối. Chúng tôi sử dụng cột đầu tiên làm khóa cho hàng và chúng tôi tổng hợp vào mảng.

Cuối cùng, chúng tôi lặp qua mảng và in giá trị trung bình theo hàng trên tất cả các tệp.

+0

Trong mã này những gì tôi hiểu là lúc đầu tất cả các giá trị từ tập tin fort.1 giữ trong mảng "tổng". Tiếp theo nó đi để đọc tập tin thứ hai fort.2 và giữ trong tổng số mảng. (Ví dụ), sau đó nó sẽ làm (tổng cộng [1] + tổng [1]/2) từ tập tin đầu tiên và thứ hai tương ứng, để có được mức trung bình. Nhưng tôi không hiểu ... Xin lỗi nếu tôi hiểu sai. – Vijay

+0

Đã chỉnh sửa để phản ánh các giả định của tôi về vấn đề này. –

+0

Cảm ơn bạn đã trả lời nhanh chóng. Hãy để tôi một lần nữa làm rõ những gì tôi muốn. Mỗi tệp (tổng cộng 500 tệp) chứa hai cột (cột thứ nhất và cột thứ hai) và với 800 hàng dòng.Tôi muốn dòng đầu tiên, 2 cột của mỗi tập tin (tất cả 500 tập tin) được thêm vào và tính trung bình và lưu trữ trong một newfile như average.output. Sau đó, nó đi đến dòng thứ hai, 2 cột của tất cả các tập tin (500 tập tin) và tính trung bình và lưu trữ trong average.output. Và nó tiếp tục cho đến khi tệp tin trung bình.output chứa 800 dòng. Chúc các bạn nhận được lời giải thích này. Xin lỗi nếu câu hỏi của tôi trong bài đăng nhầm lẫn bạn. Cảm ơn bạn trước. – Vijay

2

Giả sử cột đầu tiên là một ID:

cat fort.* | awk '{sum[$1] += $2; counts[$1]++;} END {for (i in sum) print i, sum[i]/counts[i];}' 
5

Dưới đây là một cách nhanh chóng sử dụng pasteawk:

paste fort.* | awk '{ for(i=2;i<=NF;i+=2) array[$1]+=$i; if (i = NF) print $1, array[$1]/NF*2 }' > output.file 

Giống như một số các câu trả lời khác; đây là một cách khác nhưng điều này sử dụng sort để có được đầu ra số lượng sắp xếp:

awk '{ sum[$1]+=$2; cnt[$1]++ } END { for (i in sum) print i, sum[i]/cnt[i] | "sort -n" }' fort.* 
7

awk mà không cần bất kỳ giả định trên cột 1:

awk '{a[FNR]+=$2;b[FNR]++;}END{for(i=1;i<=FNR;i++)print i,a[i]/b[i];}' fort.* 
+0

Mã này xem xét tất cả "dòng đầu tiên của tất cả các tệp đầu vào (fort.1, fort.2 ...)" và tính trung bình và sau đó đi đến dòng thứ hai của tất cả các tệp (pháo đài, pháo đài.2 ... .) cho đến 800 dòng từ mỗi tệp? Tôi cần một số lời giải thích để hiểu mã này thực sự là gì. Cảm ơn – Vijay

+0

@Vijay: Nó thực sự không .. cập nhật nó với pháo đài. * Để làm cho nó rõ ràng hơn. Bạn có thể kiểm tra nó với một tệp mẫu nhỏ để xác nhận ... – Guru

+0

Guru, Mã này hoạt động tốt. Cảm ơn bạn. Ngoài ra điều nhỏ cần phải được thêm vào. Tôi có các tập tin có tên fort.1, fort.2 và vân vân. Tôi sợ nếu tôi đặt pháo đài. *, Nó sẽ đọc fort.1, fort.10, fort.100 thay vì fort.1, fort.2 và cứ thế. Làm thế nào điều này có thể được điều trị? Cảm ơn – Vijay

Các vấn đề liên quan