Как вычесть строки (строки) с AWK

9

Я пытаюсь понять, как я могу использовать AWK для вычитания линий. Например, представьте, что входной файл:

30
20

Выход будет:

10

Теперь, в качестве теста, я пытаюсь вычислить столбец памяти «Используется» из:

$ cat /proc/meminfo

Итак, на данный момент я написал это:

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

Я пробовал следующее:

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

Но это только дает мне последний ряд данных.

Я нашел рабочее решение, но сомневаюсь, что оно самое оптимальное. Весь мой опыт программирования говорит мне, что жесткое кодирование количества строк ужасно: P

$ grep -P 'MemTotal|MemFree' /proc/meminfo | \
    awk '{print $2}' | awk 'NR == 1{s=$0} NR == 2 {s=s-$0} END {print s}'
Дилан Миус
источник
Что бы вы хотели сделать с N строк? Должен ли быть конечный результат line1_$2 - line2_$2 - lineN-$2? Вы хотите только вычесть первые два последовательных ряда?
Terdon

Ответы:

9

Вы также можете сделать это , используя awk, pasteи bc. Я нахожу этот подход легче запомнить, синтаксис awkвсегда требует от меня, чтобы искать вещи, чтобы подтвердить.

ПРИМЕЧАНИЕ. Преимущество этого подхода заключается в возможности бороться с несколькими строками вывода, вычитая 2-е, 3-е, 4-е и т. Д. Числа из 1-го.

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

подробности

Выше используется awkдля выбора столбца, который содержит числа, которые мы хотим вычесть.

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

Затем мы используем pasteдля объединения этих двух значений значения и добавляем знак минус между ними.

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

Когда мы передаем это, bcон выполняет расчет.

$ grep -P 'MemTotal|MemFree' /proc/meminfo | \
    awk '{print $2}'| paste -sd- - | bc
7513404
SLM
источник
@terdon - спасибо, что я сделал это редактирование, когда ты сделал это 8-)
slm
3

Чисто awk-решение, без лишних команд cat или grep:

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

Я вижу, что awk_FTW побеждает меня, но форматирование вывода может быть хорошим.

Johan
источник
3

Попробуй это:

grep -P 'MemTotal|MemFree' /proc/meminfo | \
awk 'NR==1{s=$2;next}{s-=$2}END{print s}'
cuonglm
источник