Cách trừ các hàng (dòng) bằng AWK


9

Tôi đang cố gắng tìm hiểu làm thế nào tôi có thể sử dụng AWK để trừ các dòng. Ví dụ, hãy tưởng tượng tệp đầu vào là:

30
20

Đầu ra sẽ là:

10

Bây giờ, như một thử nghiệm, tôi đang cố gắng tính toán cột bộ nhớ "Được sử dụng" từ:

$ cat /proc/meminfo

Vì vậy, tại thời điểm này tôi đã viết điều này:

$ grep -P 'MemTotal|MemFree' /proc/meminfo | \
    -- Here comes the calculation using AWK

Tôi đã thử như sau:

$ grep -P 'MemTotal|MemFree' /proc/meminfo | \
    awk '{print $2}' | awk '{$0-s}{s=$0} END {print s}' 

Nhưng điều này chỉ cho tôi hàng dữ liệu cuối cùng.

Tôi đã tìm thấy một giải pháp hiệu quả, nhưng tôi nghi ngờ đó là giải pháp tối ưu nhất. Tất cả kinh nghiệm mã hóa của tôi cho tôi biết rằng mã hóa cứng số lượng hàng là khủng khiếp: P

$ grep -P 'MemTotal|MemFree' /proc/meminfo | \
    awk '{print $2}' | awk 'NR == 1{s=$0} NR == 2 {s=s-$0} END {print s}'

Bạn muốn làm gì với N hàng? Có nên kết quả cuối cùng line1_$2 - line2_$2 - lineN-$2? Bạn chỉ muốn trừ hai hàng đầu tiên liên tiếp?
terdon

Câu trả lời:


9

Bạn cũng có thể làm điều này bằng cách sử awk, pastebc. Tôi thấy cách tiếp cận này dễ nhớ hơn, cú pháp awkluôn đòi hỏi tôi phải tìm kiếm mọi thứ để xác nhận.

LƯU Ý: Cách tiếp cận này có lợi thế là có thể tranh chấp với nhiều dòng đầu ra, trừ đi các số thứ 2, 3, 4, v.v. từ số 1.

$ grep -P 'MemTotal|MemFree' /proc/meminfo | \
    awk '{print $2}' | paste -sd- - | bc
7513404

Chi tiết

Ở trên sử dụng awkđể chọn cột có chứa các số chúng tôi muốn trừ.

$ grep -P 'MemTotal|MemFree' /proc/meminfo | \
    awk '{print $2}'
7969084
408432

Sau đó, chúng tôi sử dụng pasteđể kết hợp 2 giá trị giá trị này và thêm dấu trừ vào giữa chúng.

$ grep -P 'MemTotal|MemFree' /proc/meminfo | \
    awk '{print $2}'| paste -sd- -
7969084-346660

Khi chúng ta truyền cái này cho bcnó thực hiện phép tính.

$ grep -P 'MemTotal|MemFree' /proc/meminfo | \
    awk '{print $2}'| paste -sd- - | bc
7513404

@terdon - cảm ơn tôi đã thực hiện chỉnh sửa đó khi bạn thực hiện nó 8-)
slm

3

Giải pháp hoàn toàn awk, không có lệnh cat hoặc grep dự phòng:

awk '/MemTotal/ {TOT=$2} /MemFree/ {FREE=$2} END {printf("%d kB Used\n", TOT-FREE)}' /proc/meminfo

Tôi thấy awk_FTW đánh bại tôi nhưng tôi mặc dù định dạng đầu ra có thể tốt.


3

Thử cái này:

grep -P 'MemTotal|MemFree' /proc/meminfo | \
awk 'NR==1{s=$2;next}{s-=$2}END{print s}'
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.