Come sottrarre righe (linee) con AWK


9

Sto cercando di capire come posso usare AWK per sottrarre linee. Ad esempio, immagina che il file di input sia:

30
20

L'output sarebbe:

10

Ora, come test, sto provando a calcolare la colonna di memoria "Usato" da:

$ cat /proc/meminfo

Quindi al momento ho scritto questo:

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

Ho provato quanto segue:

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

Ma questo mi dà solo l'ultima riga di dati.

Ho trovato una soluzione funzionante, ma dubito che sia la migliore. Tutta la mia esperienza di programmazione mi dice che codificare con difficoltà la quantità di righe è terribile: P

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

Cosa vorresti fare con N righe? Il risultato finale dovrebbe essere line1_$2 - line2_$2 - lineN-$2? Vuoi sottrarre solo le prime due righe consecutive?
terdon

Risposte:


9

È inoltre possibile eseguire questa operazione utilizzando awk, pastee bc. Trovo questo approccio più facile da ricordare, la sintassi di awkmi richiede sempre di cercare le cose per confermare.

NOTA: questo approccio ha il vantaggio di poter contendere con più righe di output, sottraendo i numeri 2 °, 3 °, 4 °, ecc. Dal 1 °.

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

Dettagli

Quanto sopra utilizza awkper selezionare la colonna che contiene i numeri che vogliamo sottrarre.

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

Quindi utilizziamo pasteper combinare questi 2 valori e aggiungere il segno meno tra di loro.

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

Quando lo passiamo ad bcesso esegue il calcolo.

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

@terdon - grazie stavo facendo che modifica quando l'avete fatto 8-)
SLM

3

La soluzione puramente awk, nessun comando cat o grep ridondante:

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

Vedo che awk_FTW mi ha battuto, ma ho pensato che la formattazione dell'output potesse essere piacevole.


3

Prova questo:

grep -P 'MemTotal|MemFree' /proc/meminfo | \
awk 'NR==1{s=$2;next}{s-=$2}END{print s}'
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.