Cara mengurangi baris (garis) dengan AWK

9

Saya mencoba mencari tahu bagaimana saya bisa menggunakan AWK untuk mengurangi garis. Misalnya, bayangkan file input adalah:

30
20

Outputnya adalah:

10

Sekarang, sebagai ujian saya mencoba menghitung kolom memori "Bekas" dari:

$ cat /proc/meminfo

Jadi saat ini saya telah menulis ini:

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

Saya sudah mencoba yang berikut ini:

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

Tapi ini hanya memberi saya baris data terakhir.

Saya telah menemukan solusi yang berfungsi, tetapi saya ragu itu yang paling optimal. Semua pengalaman pengkodean saya memberi tahu saya bahwa pengkodean jumlah baris sangat buruk: P

$ grep -P 'MemTotal|MemFree' /proc/meminfo | \
    awk '{print $2}' | awk 'NR == 1{s=$0} NR == 2 {s=s-$0} END {print s}'
Dylan Meeus
sumber
Apa yang ingin Anda lakukan dengan baris N? Haruskah hasil akhirnya line1_$2 - line2_$2 - lineN-$2? Apakah Anda hanya ingin mengurangi dua baris pertama berturut-turut?
terdon

Jawaban:

9

Anda juga dapat melakukannya dengan menggunakan awk, paste, dan bc. Saya menemukan pendekatan ini lebih mudah diingat, sintaksis awkselalu mengharuskan saya untuk mencari sesuatu untuk mengonfirmasi.

CATATAN: Pendekatan ini memiliki keunggulan karena mampu bersaing dengan beberapa jalur output, dengan mengurangkan angka 2, 3, 4, dll. Dari angka 1.

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

Detail

Penggunaan di atas awkuntuk memilih kolom yang berisi angka yang ingin kita kurangi.

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

Kami kemudian gunakan pasteuntuk menggabungkan 2 nilai nilai ini dan menambahkan tanda minus di antaranya.

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

Ketika kami melewati ini untuk bcmelakukan perhitungan.

$ grep -P 'MemTotal|MemFree' /proc/meminfo | \
    awk '{print $2}'| paste -sd- - | bc
7513404
slm
sumber
@terdon - terima kasih saya membuat suntingan itu ketika Anda melakukannya 8-)
slm
3

Solusi murni awk, tidak ada perintah kucing atau grep yang berlebihan:

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

Saya melihat awk_FTW mengalahkan saya untuk itu tetapi saya meskipun memformat output bisa lebih baik.

Johan
sumber
3

Coba ini:

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