Comment soustraire des lignes (lignes) avec AWK

9

J'essaie de comprendre comment je peux utiliser AWK pour soustraire des lignes. Par exemple, imaginez que le fichier d'entrée est:

30
20

La sortie serait:

10

Maintenant, en tant que test, j'essaie de calculer la colonne de mémoire "utilisée" à partir de:

$ cat /proc/meminfo

Donc, pour le moment, j'ai écrit ceci:

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

J'ai essayé ce qui suit:

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

Mais cela me donne juste la dernière ligne de données.

J'ai trouvé une solution qui fonctionne, mais je doute que ce soit la plus optimale. Toute mon expérience de codage me dit que le codage en dur de la quantité de lignes est terrible: 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
la source
Que voudriez-vous faire avec N lignes? Le résultat final devrait-il être line1_$2 - line2_$2 - lineN-$2? Voulez-vous uniquement soustraire les deux premières lignes consécutives?
terdon

Réponses:

9

Vous pouvez aussi le faire en utilisant awk, pasteet bc. Je trouve cette approche plus facile à retenir, la syntaxe de awkme oblige toujours à rechercher les choses pour confirmer.

REMARQUE: Cette approche a l'avantage de pouvoir faire face à plusieurs lignes de sortie, en soustrayant les 2e, 3e, 4e, etc. numéros du 1er.

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

Détails

Les utilisations ci-dessus permettent awkde sélectionner la colonne qui contient les nombres que nous voulons soustraire.

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

Nous utilisons ensuite pastepour combiner ces 2 valeurs et ajouter le signe moins entre elles.

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

Lorsque nous le transmettons, bcil effectue le calcul.

$ grep -P 'MemTotal|MemFree' /proc/meminfo | \
    awk '{print $2}'| paste -sd- - | bc
7513404
slm
la source
@terdon - merci je faisais ce montage quand vous l'avez fait 8-)
slm
3

La solution purement awk, pas de commandes redondantes cat ou grep:

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

Je vois awk_FTW me battre, mais je pense que le formatage de la sortie pourrait être agréable.

Johan
la source
3

Essaye ça:

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