Làm cách nào để kết hợp các giá trị từ hai cột?


11

Tôi có một tập tin theo định dạng sau:

$ cat /tmp/raw
2015-01   5000   1000
2015-02   6000   2000
2015-03   7000   3000

Bây giờ, điều tôi muốn là lấy giá trị kết hợp từ cột 2 và 3 trong mỗi hàng để có kết quả như sau:

2015-01   6000
2015-02   8000
2015-03   9000

Tôi đã thử điều này nhưng nó chỉ hiển thị giá trị cuối cùng trong tệp như giá trị 2015-03.

Câu trả lời:


11

Bạn có thể thử sử dụng awk:

awk '{ print $1, $2 + $3; }' /tmp/raw

Kết quả sẽ là (tôi cho rằng giá trị cho 2015/03 sẽ là 10000):

2015-01 6000
2015-02 8000
2015-03 10000

1
Tôi không thể tin tôi đã nhận trả lời nhanh này: O, tôi không bao giờ nhận được trả lời nhanh chóng như trên bất kỳ diễn đàn khác :) cảm ơn bạn lệnh làm việc một cách hoàn hảo :)
Syed Jahanzaib

@SyedJahanzaib, Nếu câu trả lời này đã giải quyết được vấn đề của bạn, vui lòng dành chút thời gian và chấp nhận nó bằng cách nhấp vào dấu kiểm bên trái. Điều đó sẽ đánh dấu câu hỏi là đã trả lời và là cách cảm ơn được thể hiện trên các trang web Stack Exchange.
terdon

xin lỗi tôi quên đánh dấu câu trả lời và cảm ơn tất cả những người khác vì đã có thời gian và trả lời quý giá, họ cũng giúp tôi trong việc học cách đạt được các mục tiêu bằng phương pháp khác nhau :)
Syed Jahanzaib

@SyedJahanzaib, mặc dù tôi đã kiếm được huy hiệu đẹp cho câu trả lời này nhưng tôi nghĩ chính xác và toàn diện hơn là câu trả lời của terdon.
Taliezin

16

Dưới đây là một vài cách:

  1. Một cách tiếp cận awk khác

    awk '{$2+=$3;}NF--' file
    
  2. Perl

    perl -lane 'print "$F[0] ",$F[1]+$F[2]' file
    

    hoặc là

    perl -ape 's/$F[1].*/$F[1]+$F[2]/e' file
    
  3. Shell (chậm hơn / kém hiệu quả hơn so với ở trên)

    while read a b c; do echo "$a $((b + c))"; done < file
    

2
$2+=$3có thể khủng khiếp hơn
123

@ User112638726 thực sự là như vậy. Cảm ơn.
terdon

3
Bạn cũng có thể sử dụng awk '{$2+=$3}NF--'để vẫn không có trường trống 3 treo. Mặc dù đó chỉ là sở thích của tôi và nó quá giống với việc tự mình đăng bài như một câu trả lời :)
123

1
@ User112638726 bây giờ người ta thậm chí đã không xảy ra với tôi. Gọn gàng hơn nhiều, cảm ơn!
terdon

Tôi đã viết này cho bạn. Lưu ý cách không chỉ sedbằng cách nào đó quản lý để hiểu các trường - thậm chí để xác định các trường đang hoạt động và các trường w / trong các trường - nhưng, như trường hợp rõ ràng, toàn bộ khái niệm về kết hợp regrec Unix thực sự dựa trên việc chia một chuỗi thành các trường theo một mô hình ! Ai biết?
mikeerv

5
sed 's/[^ ]* */[&]P/;s//&+pc/3'|dc

... bản in ...

2015-01   6000
2015-02   8000
2015-03   10000

Vì vậy, ở trên tôi khai báo một biểu thức chính quy xác định phạm vi trường bao gồm một chuỗi các ký tự có *độ dài thay đổi ^không phải<dấu cách> ngay sau đó là một chuỗi các ký tự có *độ dài thay đổi<dấu cách> . Tuyên bố này được áp dụng đối với sedkhông gian mẫu của chuỗi, được phân tách bằng chuỗi (theo mặc định) bởi mỗi \nký tự ewline xuất hiện trong đầu vào và được thay thế đệ quy (theo mặc định) cho lần xuất hiện tiếp theo cho mỗi lần xuất hiện giống nhau.

Giao diện cho tuyên bố này là hai lần và ở mỗi cấp được quy định và chỉ định đầy đủ bởi ít nhất một ủy ban tiêu chuẩn chính thức của IEEE quốc tế để đảm bảo ứng dụng sedcú pháp lệnh có thể dự đoán được . Ví dụ, sedcú pháp API được áp dụng trong trường hợp này bằng lệnh /địa /chỉ (luôn là thành phần đầu tiên của bất kỳ sed s///lệnh ubstlation nào ) , nhưng nội dung tương tự được hiểu bởi một API cơ bản hơn như là một tập hợp con được chỉ định cho regcomp()chức năng trong thư viện C tiêu chuẩn .

Tôi có thể làm cho các báo cáo một cách tự tin, bởi vì sedkhông chỉ đơn thuần là một chương trình, nhưng, đúng hơn, biên soạn thực thi có tên sedtrên của tôi giống như Unix máy là một thực hiện của rõ ràng, lịch sử thành lập, và các tiêu chuẩn kiểm soát sed ứng dụng của regular- hệ thống của tôi biểu thức phù hợp với thư viện.


Từ sedthông số kỹ thuật:

Các sedtiện ích có trách nhiệm hỗ trợ các BREs được mô tả trong XBD cơ bản Regular Expressions ...

... nơi chúng ta tìm thấy ...

Cả hai BREs và Eres được hỗ trợ bởi giao diện Biểu hiện Matching thường xuyên dưới các khối lượng hệ thống giao diện của POSIX.1-2008 dưới regcomp(), regexec()và các chức năng liên quan.

Một ứng dụng gọi regcomp()sẽ hiển thị cho nó một chuỗi mẫu và ...

... [t] ông regcomp()hoạt động có trách nhiệm lập các biểu thức chính quy chứa trong chuỗi trỏ đến bởi mô hình lập luận và đặt kết quả trong cơ cấu preg ...

Để hành động, ứng dụng cho biết sau đó sẽ đề cập đến regcomp()chức năng đồng hành của ...

... [t] ông regexec()hoạt động so sánh chuỗi null-chấm dứt theo quy định của chuỗi với biểu hiện thường xuyên biên soạn preg khởi tạo bởi một cuộc gọi trước để regcomp()...

... regexec()sẽ điền vào các yếu tố của [một] mảng với hiệu số của các chuỗi con của chuỗi đó tương ứng với các \(subexpressions trong ngoặc đơn \)của mô hình ... mô hình riêng của mình tính như là một subexpression ...

... [t] ông regexec()hoạt động phải điền vào tất cả nkhớp yếu tố của pmatch , nơi nkhớppmatch được cung cấp bởi các ứng dụng, ngay cả khi một số yếu tố của pmatch không tương ứng với subexpressions trong mô hình .


Và khi tôi làm ...

/[^ ]* */

... sedtrước tiên biên dịch biểu thức chính quy và lưu trữ kết quả vào bộ nhớ, sau đó áp dụng tự động biên dịch được lưu trữ ở đó vào nội dung của không gian mẫu của tôi nhiều lần cần thiết để thực hiện lệnh của tôi. Mỗi lần nó thực hiện kết quả là một mảng các trường được phân tách bằng một hoặc nhiều null được phân định tại các độ lệch được trả về bởi regexec().

Và khi tôi làm ...

//

... Để chỉ ra rằng nên sử dụng biểu thức chính quy được xác định gần đây nhất, sedchỉ có thể gọi regexec()lại sử dụng lại biểu thức chính được biên dịch trước, nhưng có thể áp dụng lần này cho một đối số chuỗi đã thay đổi hoặc áp dụng các tham số nmatch mới khi tôi ra lệnh.

Cụ thể hơn vẫn là ...

  • s/[^ ]* */[&]P/
    • thay thế sự xuất hiện đầu tiên của mẫu trong không gian mẫu bằng dấu [ngoặc vuông bên trái, sau đó &chính nó, sau đó là dấu ]ngoặc vuông bên phải theo sau là một Pký tự.
  • s//&+pc/3
    • áp dụng biểu thức chính quy được sử dụng lần cuối một lần nữa cho không gian mẫu hiện tại và thay thế 3lần xuất hiện thứ ba của mẫu trong không gian mẫu bằng &chính chuỗi được nối tiếp +pc.

Và do đó, đối với mỗi dòng sedđầu vào, nó ghi vào thiết bị xuất chuẩn của nó, đưa ra dữ liệu mẫu của bạn:

[2015-01   ]P5000   1000+pc
[2015-02   ]P6000   2000+pc
[2015-03   ]P7000   3000+pc

Điều này có thể trông lạ, nhưng dcmáy tính trích dẫn các chuỗi trong đầu vào giữa các dấu ngoặc vuông và Plệnh sẽ vừa in đỉnh ngăn xếp mà không nối thêm \newline và sau đó bật ra khỏi ngăn xếp đầu vào.

Và vì vậy, sử dụng dòng đầu tiên ở đó làm ví dụ, dcsẽ làm:

  • [2015-01 ]P
    • Print và bật đầu ngăn xếp
  • 5000
    • Đẩy số 5000lên trên cùng của ngăn xếp và đẩy tất cả các yếu tố hiện có trên ngăn xếp (bây giờ không có) xuống một.
  • 1000
    • ditto, nhưng lần này, số 5000 ở đầu ngăn xếp chính bị đẩy xuống bởi một và trở thành phần tử thứ hai trên ngăn xếp.
  • +
    • Thêm hai số trên cùng của ngăn xếp với nhau, bật cả hai số đó ra khỏi ngăn xếp và đẩy tổng lên trên cùng của ngăn xếp.
    • Điều này dẫn đến một ngăn xếp chỉ bao gồm số lượng 6000.
    • Đây là lỗi cú pháp nếu một trong hai phần tử trên cùng của ngăn xếp là một [chuỗi ].
  • p
    • print trên cùng của ngăn xếp theo sau là một \newline được nối thêm mà không bật nó ra khỏi ngăn xếp.
  • c
    • clear stack

Tôi tin rằng nó hoạt động, nhưng tôi không thể phân tích nó. Nhìn chung, bạn đang thiết lập một bổ sung cho dc. Các mô hình đầu tiên có ý nghĩa. Tôi nghĩ rằng nó phù hợp với khoảng trống ngày và dấu, nhưng tôi không hiểu cái gì đặt trong dấu ngoặc của lớp nhân vật ([&]). Sẽ thật tuyệt nếu bạn đánh vần cái này.
Joe

1
@Joe - có tốt hơn không?
mikeerv

Ồ Điều đó có ý nghĩa hơn nhiều (và cho tôi thấy một loạt những điều tôi cần tìm hiểu thêm.) Đặc biệt, tôi chưa bao giờ nhận thấy việc sử dụng // để sử dụng lại mẫu hiện tại. Đó là loại điều bạn đọc và quên cho đến khi bạn gặp một ví dụ thực tế. Cảm ơn rất nhiều. Nó làm tôi bật cười khi thấy bao nhiêu sức mạnh có thể được đóng gói vào một lệnh rất nhỏ và mất bao nhiêu để giải thích nó.
Joe

@Joe - ờ ... có lẽ tôi đã hơi quá nhiệt tình ...
mikeerv
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.