Як відняти рядки (рядки) за допомогою 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? Ви хочете лише відняти перші два послідовних рядки?
тердон

Відповіді:


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

@terdon - дякую, що я робив цю редагування, коли ви це зробили 8-)
slm

3

Суто дивовижне рішення, без зайвих команд cat та grep:

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

Я бачу awk_FTW перемогли мене, але я хоч форматування виводу могло б бути непоганим.


3

Спробуйте це:

grep -P 'MemTotal|MemFree' /proc/meminfo | \
awk 'NR==1{s=$2;next}{s-=$2}END{print s}'
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.