Có thể thêm các cột liên tiếp trong AWK


7

Vì vậy, tôi có một tệp lớn chứa các giá trị đếm trong các cột. Phiên bản ngắn hơn của tệp như sau:

Id,Sample1,Sample2,Sample3,Sample4,Sample5,Sample6,Sample7,Sample8,Sample9,Sample10,Sample11,Sample12,Sample13,Sample14,Sample15,Sample16,Sample17,Sample18,Sample19,Sample20,Sample21,Sample22,Sample23,Sample24
bar,80,167,1419,2973,16846,31523,257,466,4004,6662,13862,22205,116,284,786,1198,467,853,3333,6054,18122,34030,22,41
foo,29,71,582,1143,6382,11466,99,138,1388,2176,4337,7043,55,106,349,600,211,319,1468,2418,8661,15285,12,12
qaz,23,59,478,904,4919,8538,85,147,1553,2463,5061,8094,56,84,271,411,176,291,1268,2132,7219,12436,6,13
etc,27,43,464,970,4101,8092,90,111,1441,2174,4954,7940,41,85,249,378,130,234,1075,1856,5920,10854,9,18
zxc,15,34,332,609,2568,4652,53,82,989,1592,3219,5034,46,87,315,479,104,170,759,1297,4926,8171,2,9
qwe,9,20,146,310,2932,5391,48,94,842,1349,2823,4430,23,34,115,235,113,172,811,1362,4178,7576,8,10
asd,16,39,388,687,2796,5303,51,110,763,1216,2610,4165,50,79,351,603,113,156,824,1345,3337,6168,4,9
abc,6,16,91,192,385,654,21,32,326,496,7884,12266,10,19,56,89,41,62,251,367,1545,2657,,4
xyz,14,33,249,538,1634,2983,28,71,555,952,1697,2712,23,34,111,167,95,148,650,1131,3204,5814,4,12

Điều tôi muốn làm là tính tổng các cột liên tiếp (sample1 + sample2, sample3 + sample4, ...) sao cho:

bar,247,4392,...
foo,100,1725,...
qaz,82,1382,...
...

Tôi đã thử các vòng lặp trên NF nhưng dường như in mọi thứ trên các dòng riêng biệt, cũng là những con số không thực sự chính xác ...

> awk -F, 'NR > 1 {for(i=2; i<=NF; i=i+2){print ($i + $i+1)}}' short.csv 
161
2839
33693
515
8009
27725
233
1573
935
6667
36245
45
59
1165
...

Có thể làm điều này trong awk hoặc tương tự trọng lượng nhẹ, dòng lệnh script-fu?


@Rahul Các giá trị dưới cột SampleN, đã cố gắng làm rõ nó trong phần thân câu hỏi.
posdef

3
thay thế $i+1bằng $(i+1).
meuh

@meuh Điều đó giải quyết vấn đề bổ sung, tuy nhiên các giá trị vẫn nằm trên các hàng riêng biệt. Tôi cũng không chắc chắn làm thế nào để có được cột đầu tiên trên cùng một dòng
posdef

1
sử dụng printf "%d,",... cho print.
meuh

Câu trả lời:


9

Vấn đề bạn gặp phải $i + $i+1là vấn đề thực sự $i + $i + 1không phải là điều bạn muốn.

Thay vào đó là một cái gì đó như

awk -F, 'NR > 1 { printf("%s",$1)
                  for(i=2;i<=NF;i+=2) { printf(",%d",$i+$(i+1)) }
                  print ""
                }
'

Các kết quả:

bar,247,4392,48369,723,10666,36067,400,1984,1320,9387,52152,63
foo,100,1725,17848,237,3564,11380,161,949,530,3886,23946,24
qaz,82,1382,13457,232,4016,13155,140,682,467,3400,19655,19
etc,70,1434,12193,201,3615,12894,126,627,364,2931,16774,27
zxc,49,941,7220,135,2581,8253,133,794,274,2056,13097,11
qwe,29,456,8323,142,2191,7253,57,350,285,2173,11754,18
asd,55,1075,8099,161,1979,6775,129,954,269,2169,9505,13
abc,22,283,1039,53,822,20150,29,145,103,618,4202,4
xyz,47,787,4617,99,1507,4409,57,278,243,1781,9018,16

Tuyệt diệu! Cảm ơn bạn .. Tôi cho rằng nói chung là tốt hơn để đặt tập lệnh đó trong một tập tin riêng biệt? Tôi nói rằng phần lớn là do việc quản lý dấu ngoặc đơn trên nhiều dòng dễ dàng hơn ..
posdef

2
Đó là vấn đề của hương vị. Tôi có xu hướng nội tuyến các tập lệnh awk ngắn như thế này để có ít phụ thuộc tệp bên ngoài hơn. awkkhông quan tâm quá nhiều về các dòng mới trong kịch bản này, do đó bạn thậm chí có thể đặt tất cả trên một dòng bằng ;dấu phân cách; awk -F, 'NR > 1 { printf("%s",$1) ; for(i=2;i<=NF;i+=2) { printf(",%d",$i+$(i+1)) } ; print "" }'
Stephen Harris
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.